用户管理器VerifyUserTokenAsync总是返回false

19

我正在这样生成用户令牌

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。

为什么Verify方法不能在单独的请求中验证代码?我有遗漏了什么明显的东西吗?

6个回答

24

我抓耳挠腮了几个小时,最终弄明白了这一点。您需要对代码进行URL编码,我决定使用HttpUtility类来实现。

HttpUtility.UrlEncode(code);

在验证代码时,您不需要对代码进行URL解码。


1
我花了很长时间才找到这个答案...但是当我找到它时,解决了我的问题!谢谢。 - Cos Callis
5
我不确定你安装了哪个版本的ASP.NET身份验证。但是我正在使用2.2.1版本,当我验证代码时,我绝对必须使用HttpUtility.UrlDecode(code)。否则,它总是会返回false。 - brsfan
如果您必须显式使用UrlDecode来验证代码,则在创建URL时可能对其进行了双重编码。这是不必要的。 - Simon_Weaver
在标记上使用 UrlDecode 对我不起作用,我不需要对标记进行解码。 - Tristan Djahel
我想补充一点,VerifyUserToken肯定可以处理URL解码的令牌,所以如果你看到它返回false,我不认为这可能是答案。 - Josh
1
在将令牌传递给VerifyUserTokenAsync之前,最有可能需要使用HttpUtility.UrlDecode。至少我似乎需要这样做。 - Jedidja

3

经过两天的研究,我发现还有另一个原因可能导致这个问题。如果您在Startup.cs文件中的ConfigureServices(IServiceCollection services)方法中,请确保以下内容:

services.AddAuthentication

出现在之前

services.AddIdentity

否则,对VerifyUserTokenAsync的调用将始终返回false。

0

在使用此方法之前无法解决此问题:

 UserManager.VerifyUserTokenAsync(userId, AccountLockedOutPurpose, code).WithCurrentCulture<bool>();

.WithCurrentCulture() - 在所有方法中使用,例如ResetPasswordAsync等)


0

对我来说,我遇到了同样的问题。而解决方案很简单。

在我的情况下,我添加了带有空格的目的,像这样“电子邮件确认”。 当我删除任何空格“电子邮件确认”时,问题得到解决。

bool IsTokenValed = await userManager.VerifyUserTokenAsync(user, userManager.Options.Tokens.EmailConfirmationTokenProvider, "EmailConfirmation", token);

0

不确定 OP 是否在使用 .Net Core,但如果有人遇到这个问题并且正在使用依赖注入,对我来说解决方案是将 UserManager 作为单例进行作用域处理。

services.AddSingleton<UserManager<YourUserAccountModel>>();

我相信这是因为当用户点击他们收件箱中的确认电子邮件链接时,一个新的UserManager实例被注入到控制器中,并且没有使用生成令牌的同一个密钥。因此它无法验证令牌。

0
在我的情况下,当需要时我会实例化一个UserManager,而不是在启动管道中为每个Owin上下文生成一个。行为方面,如果我使用创建它的同一UserManager实例验证令牌,它将返回true。但是,如果我执行实际的忘记密码流程,在单独的请求中进行验证,则始终为false。
将我的设置更改为每个owin上下文创建一个UserManager解决了我的问题。显然,在验证令牌时,与Owin有一些依赖关系。
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接