我正在尝试验证用户的电子邮件确认令牌,但无论我做什么,总是收到 INVALID TOKEN 错误。
我的代码很简单
生成令牌
EmailVerificationCode = await userManager.GenerateEmailConfirmationTokenAsync(user);
EmailVerificationHTMLFormatCode = HttpUtility.UrlEncode(EmailVerificationCode);
验证令牌
var result = await userManager.ConfirmEmailAsync(user, code);
我总是收到 INVALID TOKEN 错误。
我尝试过的事情
HttpUtility.UrlDecode(Code)
在接收端解码令牌HttpUtility.UrlEncode
来验证它我还经历了以下解决方案
无论我做什么,它总是一个无效的令牌,我可以清楚地看到该令牌是 100% 正确的。
知道我做错了什么吗?
编辑 - 如果这有帮助,我的
Startup.cs
有以下身份配置
// For Identity
services.AddIdentity<ApplicationUser, IdentityRole>(o =>
{
// configure identity options
o.Password.RequireDigit = false;
o.Password.RequireLowercase = false;
o.Password.RequireUppercase = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequiredLength = 6;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
在我回答之前,有几个关于此实现的问题。
您可以采取什么措施来解决此问题,创建一个客户 DataProtectionProvider,如下所示,
public class EmailConfirmationTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class
{
public EmailConfirmationTokenProvider(IDataProtectionProvider dataProtectionProvider,
IOptions<EmailConfirmationTokenProviderOptions> options,
ILogger<DataProtectorTokenProvider<TUser>> logger)
: base(dataProtectionProvider, options, logger)
{
}
}
public class EmailConfirmationTokenProviderOptions : DataProtectionTokenProviderOptions
{
}
然后注入配置服务,其生命周期为2小时。
services.AddTokenProvider<EmailConfirmationTokenProvider<User>>("emailconfirmation");
服务.配置(选择=> opt.TokenLifespan = TimeSpan.FromHours(3));
谢谢你
就我而言,问题是我从查询([FromQuery] 属性)中获取了令牌,并且该控制器已经自动运行 UrlDecode(),所以我运行了两次。检查创建和接收时的令牌是否相同。
我发现这个无效令牌问题遍布互联网,但我实际上并没有找到具体的答案,对于某些人来说可能是一个非常简单的问题!
希望这可以对其他人有所帮助,并在某些时候与他们相同:-
您生成包含在电子邮件内容中的令牌,如下所示:-
var token = await this.userManager.GenerateEmailConfirmationTokenAsync(user);
encodedToken = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(token));
验证令牌时,您必须记住反转编码:-
var decodedToken = System.Text.Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(encodedToken));
var result = await this.userManager.ConfirmEmailAsync(user, decodedToken);
我花了一个小时开始调查数据保护提供商和各种类型,但答案很简单,当我意识到时我感觉有点愚蠢!