UserManager VerifyUserTokenAsync 始终为 False
UserManager VerifyUserTokenAsync Always False
我正在像这样生成用户令牌
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
}
它 returns 正确。
为什么 Verify 方法无法验证单独请求中的代码?我是否漏掉了一些明显的东西?
我拔头发几个小时后终于想通了。您需要 URL 对代码进行编码,为此我决定使用 HttpUtility class。
HttpUtility.UrlEncode(code);
在验证代码时,您不需要需要URL解码代码。
在没有使用这个之前无法解决这个问题:
UserManager.VerifyUserTokenAsync(userId, AccountLockedOutPurpose, code).WithCurrentCulture<bool>();
.WithCurrentCulture() - 用于 ResetPasswordAsync 等所有方法)
刚刚在这个问题上耗费了 2 天时间,这可能是您遇到这种情况的另一个原因。
在您的 Startup.cs - ConfigureServices(IServiceCollection services) 方法中,确保:
services.AddAuthentication
出现在
之前
services.AddIdentity
否则对 VerifyUserTokenAsync 的调用将始终 return false
在我的情况下,我在需要时按需实例化一个 UserManager,而不是在我的启动管道中为每个 Owin 上下文生成一个。在行为方面,如果我使用创建令牌的同一 UserManager 实例验证令牌,它将 return 为真。但是如果我做了一个实际的忘记密码流程,其中验证是在一个单独的请求中,它总是错误的。
切换我的设置以便为每个 owin 上下文创建一个 UserManager 为我解决了这个问题。显然,在验证令牌时对 Owin 有一定的依赖性。
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
不确定 OP 是否正在使用 .Net Core,但如果有人遇到这个问题并且您正在使用依赖注入,我的解决方案是将 UserManager 的范围限定为单例。
services.AddSingleton<UserManager<YourUserAccountModel>>();
我认为这是因为当用户点击收件箱中的确认邮件 link 时,一个新的 UserManager 实例被注入到控制器中,并且没有用于生成令牌的相同密钥首先。因此它无法验证令牌。
对我来说,我遇到了同样的问题。解决方案非常简单。
在我的例子中,我添加了带有白色 space 的目的,例如“电子邮件确认”。
当我删除任何白色 space "EmailConfirmation".
时问题就解决了
bool IsTokenValed = await userManager.VerifyUserTokenAsync(user, userManager.Options.Tokens.EmailConfirmationTokenProvider, "EmailConfirmation", token);
我正在像这样生成用户令牌
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
}
它 returns 正确。
为什么 Verify 方法无法验证单独请求中的代码?我是否漏掉了一些明显的东西?
我拔头发几个小时后终于想通了。您需要 URL 对代码进行编码,为此我决定使用 HttpUtility class。
HttpUtility.UrlEncode(code);
在验证代码时,您不需要需要URL解码代码。
在没有使用这个之前无法解决这个问题:
UserManager.VerifyUserTokenAsync(userId, AccountLockedOutPurpose, code).WithCurrentCulture<bool>();
.WithCurrentCulture() - 用于 ResetPasswordAsync 等所有方法)
刚刚在这个问题上耗费了 2 天时间,这可能是您遇到这种情况的另一个原因。
在您的 Startup.cs - ConfigureServices(IServiceCollection services) 方法中,确保:
services.AddAuthentication
出现在
之前services.AddIdentity
否则对 VerifyUserTokenAsync 的调用将始终 return false
在我的情况下,我在需要时按需实例化一个 UserManager,而不是在我的启动管道中为每个 Owin 上下文生成一个。在行为方面,如果我使用创建令牌的同一 UserManager 实例验证令牌,它将 return 为真。但是如果我做了一个实际的忘记密码流程,其中验证是在一个单独的请求中,它总是错误的。
切换我的设置以便为每个 owin 上下文创建一个 UserManager 为我解决了这个问题。显然,在验证令牌时对 Owin 有一定的依赖性。
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
不确定 OP 是否正在使用 .Net Core,但如果有人遇到这个问题并且您正在使用依赖注入,我的解决方案是将 UserManager 的范围限定为单例。
services.AddSingleton<UserManager<YourUserAccountModel>>();
我认为这是因为当用户点击收件箱中的确认邮件 link 时,一个新的 UserManager 实例被注入到控制器中,并且没有用于生成令牌的相同密钥首先。因此它无法验证令牌。
对我来说,我遇到了同样的问题。解决方案非常简单。
在我的例子中,我添加了带有白色 space 的目的,例如“电子邮件确认”。 当我删除任何白色 space "EmailConfirmation".
时问题就解决了bool IsTokenValed = await userManager.VerifyUserTokenAsync(user, userManager.Options.Tokens.EmailConfirmationTokenProvider, "EmailConfirmation", token);