我知道,这个问题在SO中被多次询问过,但我的问题有点不同。
我遇到GenerateEmailConfirmationTokenAsync
和ConfirmEmailAsync
方法的奇怪问题。
在发送电子邮件之前,我正在使用HttpUtility.UrlEncode
和HttpUtility.UrlDecode
方法。
奇怪的是,在创建用户和收到邮件之后,我永远无法重现任何错误。但是在相同的环境中,有10个用户报告了无效令牌的问题。
我搜索了一下,我发现它可能由于机器密钥而发生,如果IIS重新启动或某事或发布后可能会更改。所以为了解决这个问题,我已经生成了一个机器密钥并保存在web.config中,但问题仍然存在。
我在Azure App Service中托管此内容。
还有什么其他问题的想法?
更新:我在这里添加代码供您查看
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = new Uri(string.Format("{0}?userId={1}&code={2}", ConfigurationManager.AppSettings["EmailConfirmationURL"], user.Id, HttpUtility.UrlEncode(code)));
string emailTemplate = MailTemplates.UserRegistrationEmailTemplate(FirstName, CompanyName, callbackUrl);
await CustomEmail.SendEmail(new List<string> { user.Email }, "Confirm your account", emailTemplate);
确认工作为
IdentityResult result = await UserManager.ConfirmEmailAsync(userId, HttpUtility.UrlDecode(code));
答案 0 :(得分:0)
一个可能的原因可能是,如果用户花费太长时间提交令牌,则令牌在验证之前到期。令牌具有生命周期,在它们失效之前必须使用它们。默认TokenLifespanis
一天(24小时)。
检查身份配置代码,以查看您对令牌生命周期所做的任何更改。
例如,以下代码将令牌设置为在3小时后过期
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>
(dataProtectionProvider.Create("ASP.NET Identity"))
{
TokenLifespan = TimeSpan.FromHours(3)
};
}
使用上面的代码,忘记的密码和电子邮件确认令牌将在3小时后过期。在到期后尝试使用令牌的用户将获得无效的令牌错误。
OP表示无法重现该问题。这可能是因为令牌在令牌生命周期内得到验证。
答案 1 :(得分:0)
请使用Url.Action
而不是使用字符串连接创建网址。 Url.Action
在最新的MVC版本中进行幕后编码,您可以避免编码和解码操作。
以下是您可以使用的代码段。
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new
{
userId = user.Id,
code = code,
returnUrl = model.ReturnUrl
}, protocol: Request.Url.Scheme);