【问题标题】:UserManager VerifyUserTokenAsync Always FalseUserManager VerifyUserTokenAsync 总是 False
【发布时间】:2015-07-08 15:26:55
【问题描述】:

我正在像这样生成一个用户令牌

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 方法的响应总是错误的。

如果我要生成代码并在同一操作中进行验证

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

}

它返回真。

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

【问题讨论】:

    标签: asp.net-mvc asp.net-identity asp.net-identity-2


    【解决方案1】:

    在拉了几个小时的头发后,我终于想通了。您需要对代码进行 URL 编码,我决定为此使用 HttpUtility 类。

    HttpUtility.UrlEncode(code);
    

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

    【讨论】:

    • 我花了很长时间才找到这个答案......但是当我这样做时,它解决了我的问题!谢谢。
    • 我不确定您安装了哪个版本的 ASP.NET Identity。但我使用的是 2.2.1 版本,当我验证代码时,我绝对必须使用 HttpUtility.UrlDecode(code)。否则,它总是返回 false。
    • 如果您必须明确使用 UrlDecode 来验证代码,那么您可能在创建 URL 时对其进行了双重编码。应该没有必要。
    • 在令牌上使用 UrlDecode 对我不起作用。我不必解码令牌
    • 我想补充一点,VerifyUserToken 当然可以处理 URL 解码的令牌,所以如果你看到它返回 false,我不明白这怎么可能是答案。
    【解决方案2】:

    刚刚在这个问题上烧了 2 天,这可能是您遇到这种情况的另一个原因。

    在您的 Startup.cs - ConfigureServices(IServiceCollection services) 方法中,确保:

    services.AddAuthentication
    

    出现之前

    services.AddIdentity
    

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

    【讨论】:

      【解决方案3】:

      在没有使用这个之前无法解决这个问题:

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

      .WithCurrentCulture() - 用于所有方法,例如 ResetPasswordAsync 等)

      【讨论】:

        【解决方案4】:

        在我的情况下,我在需要时按需实例化一个 UserManager,而不是在我的启动管道中为每个 Owin 上下文生成一个。行为方面,如果我使用创建它的同一个 UserManager 实例验证了该令牌,它将返回 true。但是,如果我做了一个实际的忘记密码流程,其中验证在单独的请求中,它总是错误的。

        切换我的设置以便根据 owin 上下文创建 UserManager 为我解决了这个问题。显然,在验证令牌时,对 Owin 有一些依赖。

                    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        

        【讨论】:

          【解决方案5】:

          不确定 OP 是否使用 .Net Core,但如果有人遇到此问题并且您正在使用依赖注入,我的解决方案是将 UserManager 限定为单例。

          services.AddSingleton&lt;UserManager&lt;YourUserAccountModel&gt;&gt;();

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

          【讨论】:

            【解决方案6】:

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

            在我的例子中,我添加了类似“电子邮件确认”这样的空白的目的。 当我删除任何空白“EmailConfirmation”后,问题就解决了。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-07-20
              • 2021-11-05
              • 2018-11-05
              相关资源
              最近更新 更多