首页 > 解决方案 > ConfirmEmailAsync() 无论如何都会得到无效的令牌

问题描述

我正在尝试验证用户的电子邮件确认令牌,但无论我做什么,总是会收到INVALID TOKEN错误。

我的代码很简单

生成令牌

EmailVerificationCode = await userManager.GenerateEmailConfirmationTokenAsync(user);
EmailVerificationHTMLFormatCode = HttpUtility.UrlEncode(EmailVerificationCode);

验证令牌

 var result = await userManager.ConfirmEmailAsync(user, code);

我总是收到INVALID TOKEN错误。

我尝试过的事情

  1. 通过将生成的令牌和接收的令牌放入数据库来检查它们以进行验证,它们完全相同。
  2. 尝试使用HttpUtility.UrlDecode(Code)在接收端解码令牌
  3. 试图只使用 RAW 令牌而不HttpUtility.UrlEncode进行验证

我还经历了以下解决方案

  1. Asp.net 2.0 身份,ConfirmEmailAsync() 获取无效令牌
  2. 令牌无效。在使用 UserManager.ConfirmEmailAsync(user.Id, code) 验证电子邮件验证码时
  3. AspNet.Identit 2.1.0 ConfirmEmailAsync 始终返回无效令牌
  4. Asp.NET Identity 2 给出“无效令牌”错误

不管我做什么,它总是一个无效的令牌,我可以清楚地看到令牌是 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();

标签: c#asp.net-coreasp.net-core-webapiasp.net-core-identity

解决方案


在我回答之前,有几个关于这个实现的问题。

  1. 您是否实现了自定义 DataProtectionProvider?
  2. 您是否覆盖默认令牌生命周期为 x 小时数?

你可以做些什么来解决这个问题,创建一个客户 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");

services.Configure(opt => opt.TokenLifespan = TimeSpan.FromHours(3));

谢谢


推荐阅读