【问题标题】:ASP.NET Identity 2 Email Confirmation Invalid TokenASP.NET Identity 2 电子邮件确认无效令牌
【发布时间】:2024-05-18 22:40:02
【问题描述】:

我知道,这个问题在 SO 中已经被问过很多次了,但是我的问题有点不同。

GenerateEmailConfirmationTokenAsyncConfirmEmailAsync 方法有一个奇怪的问题。

在发送电子邮件之前,我正确地使用了HttpUtility.UrlEncodeHttpUtility.UrlDecode 方法。

奇怪的是,在创建用户和收到邮件后,我永远无法重现任何错误。但是在同样的环境下,10个注册用户中就有3个反映了Invalid Token的问题。

我进行了更多搜索,发现它可能是由于机器密钥而发生的,如果重新启动 IIS 或其他原因或发布后,机器密钥可能会发生变化。所以为了解决这个问题,我生成了一个机器密钥并保存在 web.config 中,但问题似乎仍然存在。

我将其托管在 Azure 应用服务中。

想知道还有什么问题吗?

更新:我在这里添加代码供大家查看

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));

【问题讨论】:

  • 如果用户提交令牌的时间过长,一个可能的原因可能是令牌在提交之前就过期了。令牌有一个生命周期,在它们失效之前必须在该生命周期内使用。
  • 虽然您确信自己正确编码了令牌。展示你做了什么。可能更多地关注代码可以发现任何问题。
  • 你看到了吗:tech.trailmax.info/2015/05/…你没有提到用户的安全标记 - 这可能是原因。
  • @trailmax 是的,我已经转至该站点,只是为了在此处发布问题之前添加 machine.config。幸运的是,我对 AspNetUsers 表中的所有用户都有 securitystamp。
  • @KrishnanduSarkar 你是怎么解决你的问题的,我也遇到了同样的问题,我也在这里创建了线程*.com/questions/54501112/…,请与我们分享你的答案

标签: c# asp.net-mvc-4 asp.net-identity-2 email-confirmation


【解决方案1】:

一个可能的原因是,如果用户提交令牌的时间过长,则令牌在验证之前就已过期。令牌有一个生命周期,在它们失效之前必须在该生命周期内使用。默认TokenLifespanis 一天(24 小时)。

检查身份配置代码以了解令牌寿命是否有任何更改。

例如以下代码将令牌设置为在 3 小时后过期

if (dataProtectionProvider != null)
{
    manager.UserTokenProvider =
       new DataProtectorTokenProvider<ApplicationUser>
          (dataProtectionProvider.Create("ASP.NET Identity"))
          {                    
             TokenLifespan = TimeSpan.FromHours(3)
          };
}

使用上面的代码,忘记密码和电子邮件确认令牌将在 3 小时后过期。过期后尝试使用令牌的用户将收到无效令牌错误。

OP 表示无法重新创建问题。这可能是因为令牌在令牌生命周期内得到验证。

【讨论】:

    【解决方案2】:

    请使用Url.Action 而不是使用字符串连接创建网址。 Url.Action 在最新的 MVC 版本中进行幕后编码,可以避免编码和解码操作。

    以下是您可以使用的代码 sn-p。

    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);
    

    【讨论】:

      最近更新 更多