如何为ASP.NET Core中GenerateUserTokenAsync生成的重置密码验证码设置自定义过期时间
解决特定场景验证码的自定义过期时间问题
问题的核心在于你当前使用的是TokenOptions.DefaultPhoneProvider(默认的手机号令牌提供者),但你自定义的是密码重置令牌提供者,两者属于不同的令牌类型,所以自定义的过期配置根本没作用到你生成的短信验证码上。下面是针对你的需求的完整解决方案:
步骤1:创建自定义短信验证码令牌提供者及配置选项
我们需要专门为这个"重置密码短信验证码"场景创建一个独立的令牌提供者,设置2分钟的有效期:
// 自定义令牌提供者,仅用于重置密码的短信验证码 public class SmsResetPasswordTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class { public SmsResetPasswordTokenProvider( IDataProtectionProvider dataProtectionProvider, IOptions<SmsResetPasswordTokenProviderOptions> options) : base(dataProtectionProvider, options) { } } // 配置该提供者的令牌有效期为2分钟 public class SmsResetPasswordTokenProviderOptions : DataProtectionTokenProviderOptions { public SmsResetPasswordTokenProviderOptions() { // 给这个提供者起个唯一名称,后面要用到 Name = "SmsResetPasswordTokenProvider"; TokenLifespan = TimeSpan.FromMinutes(2); } }
步骤2:在服务容器中注册自定义提供者
在Startup.cs(或者.NET 6+的Program.cs)中,把这个自定义提供者添加到Identity的令牌映射中,并注册为服务:
services.AddDefaultIdentity<IdentityUser>(config => { // 将自定义提供者添加到Identity的令牌提供者映射 config.Tokens.ProviderMap.Add("SmsResetPassword", new TokenProviderDescriptor( typeof(SmsResetPasswordTokenProvider<IdentityUser>))); }) .AddEntityFrameworkStores<ApplicationDbContext>() // 注册自定义令牌提供者的服务实例 .AddTokenProvider<SmsResetPasswordTokenProvider<IdentityUser>>("SmsResetPassword");
步骤3:修改生成和验证验证码的代码
把你原来使用的TokenOptions.DefaultPhoneProvider替换成我们自定义的提供者名称"SmsResetPassword":
修改ForgotPassword的生成代码:
var code = await _userManager .GenerateUserTokenAsync(user, "SmsResetPassword", "ResetPasswordTokenPurpose"); // 你的其他代码不变...
修改ResetPassword的验证代码:
var tokenVerified = await _userManager .VerifyUserTokenAsync(user, "SmsResetPassword", "ResetPasswordTokenPurpose", Input.Code); // 你的其他代码不变...
为什么之前的方案无效?
你之前自定义的是PasswordResetTokenProvider,并把它设置为全局的密码重置令牌提供者,但你实际生成验证码时用的是DefaultPhoneProvider(手机号令牌提供者),这是两个完全独立的令牌提供者体系,所以你的自定义过期时间根本不会作用到短信验证码上。
通过上面的步骤,我们创建了一个仅用于"重置密码短信验证码"的独立令牌提供者,既实现了2分钟的过期时间,又不会影响全局其他令牌的有效期。
内容的提问来源于stack exchange,提问作者Maryam
相关产品推荐
相关产品推荐

