我正在生成像这样的用语
public async Task GenerateCode()
{
var code = await UserManager.GenerateUserTokenAsync("heymega", new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"));
}
然后我通过单独的请求将相同的令牌传递给另一个动作
public async Task ValidateCode(string code)
{
var valid = await UserManager.VerifyUserTokenAsync(new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"), "heymega", code); //Returns False
}
但是,VerifyUserTokenAsync
方法的响应始终为false。
如果我要生成代码并在同一操作中进行验证
public async Task GenerateCode()
{
var code = await UserManager.GenerateUserTokenAsync("heymega", new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"));
var valid = await UserManager.VerifyUserTokenAsync(new Guid("16139fcd-7ae0-449c-ad1c-f568bbe46744"), "heymega", code); //Returns True
}
它返回true。
为什么验证方法无法在单独的请求中验证代码?我错过了一些明显的东西吗?
答案 0 :(得分:7)
我把头发拉了几个小时后终于弄明白了。你需要对代码进行URL编码,我决定使用HttpUtility类。
HttpUtility.UrlEncode(code);
在验证代码时,不需要对代码进行URL解码。
答案 1 :(得分:1)
刚刚在这个问题上烧了2天,这可能是你发生的另一个原因。
在您的Startup.cs - ConfigureServices(IServiceCollection服务)方法中,确保:
services.AddAuthentication
出现在
之前services.AddIdentity
否则对VerifyUserTokenAsync的调用将始终返回false
答案 2 :(得分:0)
在没有使用它之前无法解决这个问题:
UserManager.VerifyUserTokenAsync(userId, AccountLockedOutPurpose, code).WithCurrentCulture<bool>();
.WithCurrentCulture() - 用于所有方法,例如ResetPasswordAsync等。)
答案 3 :(得分:0)
在我的情况下,我需要在需要时实例化一个UserManager,而不是在启动管道中为每个Owin上下文生成一个UserManager。从行为角度来看,如果我使用创建令牌的UserManager相同实例来验证令牌,则它将返回true。但是,如果我进行了一次实际的忘记密码流程,其中的验证是在单独的请求中进行的,那么它总是错误的。
切换设置,以便在每个上下文上下文中创建UserManager可以为我解决此问题。显然,在验证令牌时,对Owin有一定的依赖性。
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
答案 4 :(得分:0)
不确定 OP 是否使用 .Net Core,但如果有人遇到这个问题并且您正在使用依赖注入,我的解决方案是将 UserManager 范围设为单例。
services.AddSingleton<UserManager<YourUserAccountModel>>();
我相信这是因为当用户点击收件箱中的确认电子邮件链接时,一个新的 UserManager 实例被注入控制器,并且没有用于生成令牌的相同密钥。因此它无法验证令牌。