.NET Core Identity自定义令牌提供者如何生成6位数字令牌
当前已配置自定义令牌提供者,相关代码及运行情况如下:
身份服务配置代码
services.AddIdentity<ApplicationUser, IdentityRole>(options => { options.Tokens.ProviderMap.Add("CustomEmailConfirmationTokenProvider", new TokenProviderDescriptor(typeof(CustomEmailConfirmationTokenProvider<ApplicationUser>))); options.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmationTokenProvider"; }) .AddEntityFrameworkStores<IdentityDbContext>() .AddTokenProvider<CustomEmailConfirmationTokenProvider<ApplicationUser>>("CustomEmailConfirmationTokenProvider");
自定义令牌提供者类代码
public class CustomEmailConfirmationTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class { public CustomEmailConfirmationTokenProvider(IDataProtectionProvider dataProtectionProvider,IOptions<CustomEmailConfirmationTokenProviderOptions> options , ILogger<DataProtectorTokenProvider<TUser>> logger) : base(dataProtectionProvider, options,logger) { } } public class CustomEmailConfirmationTokenProviderOptions : DataProtectionTokenProviderOptions { public CustomEmailConfirmationTokenProviderOptions() { Name = "CustomEmailConfirmationTokenProvider"; TokenLifespan = TimeSpan.FromMinutes(1); } }
令牌生成与验证代码
生成令牌:
var myToken = await usrManager.GenerateUserTokenAsync(user, "CustomEmailConfirmationTokenProvider", UserManager<object>.ResetPasswordTokenPurpose);
验证令牌:
var isValid = await usrManager.VerifyUserTokenAsync(userinfo, "CustomEmailConfirmationTokenProvider", UserManager<object>.ResetPasswordTokenPurpose, model.Token);
当前代码可正常运行,但生成的是长加密字符串:
CfDJ8IvIvIomoPJKkcJtJSNCN4wB6Fp82OPzYvkVaHtBzJBjY9EwOBt2nMg1WudWBTc1giurpRIXhSHeJTe3CLswJEOL7nng9Hd7H/ctDVNSEL5eBnzXVZpvSNmVCvgwIg3cwSNtcjjsYmGFA01EgyEkXXkBZg+jLDiEsKU8YgmaoQd5bOLE3WLopZo2lboG7dOnZv777SMHitbQNJ2SdRyZf2aMAybKAkHnKGIR3ZSyQXRM
需要将令牌修改为6位纯数字格式,请问需调整哪些部分?
你当前使用的DataProtectorTokenProvider是基于数据保护API生成加密长令牌的,要生成6位数字验证码,需要替换为基于TOTP(基于时间的一次性密码)的令牌提供者,具体修改步骤如下:
1. 重写自定义令牌提供者类
替换原有的CustomEmailConfirmationTokenProvider和CustomEmailConfirmationTokenProviderOptions,改为继承TotpSecurityStampBasedTokenProvider<TUser>(ASP.NET Core Identity内置的数字验证码提供者):
public class CustomDigitTokenProvider<TUser> : TotpSecurityStampBasedTokenProvider<TUser> where TUser : class { public CustomDigitTokenProvider(ILogger<TotpSecurityStampBasedTokenProvider<TUser>> logger) : base(logger) { } } public class CustomDigitTokenProviderOptions : TotpSecurityStampBasedTokenProviderOptions { public CustomDigitTokenProviderOptions() { Name = "CustomDigitTokenProvider"; // 保留原有的1分钟有效期设置 TokenLifespan = TimeSpan.FromMinutes(1); // 指定生成6位数字令牌 Digits = 6; } }
2. 更新身份服务配置
修改AddIdentity中的令牌提供者配置,替换为新的数字令牌提供者:
services.AddIdentity<ApplicationUser, IdentityRole>(options => { options.Tokens.ProviderMap.Add("CustomDigitTokenProvider", new TokenProviderDescriptor(typeof(CustomDigitTokenProvider<ApplicationUser>))); // 若需将此提供者作为默认邮件确认提供者,保留该行;按需调整即可 options.Tokens.EmailConfirmationTokenProvider = "CustomDigitTokenProvider"; }) .AddEntityFrameworkStores<IdentityDbContext>() .AddTokenProvider<CustomDigitTokenProvider<ApplicationUser>>("CustomDigitTokenProvider");
3. 更新令牌生成与验证代码
将令牌提供者名称替换为新的CustomDigitTokenProvider:
生成令牌:
var myToken = await usrManager.GenerateUserTokenAsync(user, "CustomDigitTokenProvider", UserManager<object>.ResetPasswordTokenPurpose);
验证令牌:
var isValid = await usrManager.VerifyUserTokenAsync(userinfo, "CustomDigitTokenProvider", UserManager<object>.ResetPasswordTokenPurpose, model.Token);
补充说明
TotpSecurityStampBasedTokenProvider会基于用户的安全戳和当前时间生成数字令牌,自动处理有效期校验,无需额外编写复杂逻辑。- 生成的令牌为纯6位数字字符串,完全符合需求。
内容的提问来源于stack exchange,提问作者Steven Sann

