【问题标题】:Asp.net Core Email confirmation sometimes says InvalidTokenAsp.net Core 电子邮件确认有时会显示 InvalidToken
【发布时间】:2019-06-27 07:21:19
【问题描述】:

我正在使用 asp.net 核心身份 2.1,我在电子邮件确认方面遇到了一个随机问题,虽然电子邮件确认有时会显示 result.Error = InvalidToken。令牌也没有过期。

注意:我们正在使用多台服务器,我们还将密钥存储在一个地方,以便所有服务器使用相同的密钥。

用于电子邮件确认的代码 sn-p。

电子邮件确认

var confCode = await _userManager.GenerateEmailConfirmationTokenAsync(user);
        var callbackUrl = Url.Action("ConfirmEmail", "Account", new
        {
            userId = user.Id,
            code = WebUtility.UrlEncode(confCode)
        }, protocol: HttpContext.Request.Scheme);

        string confirmationEmailBody = string.Format(GetTranslatedResourceString("ConfirmationEmailBody"), "<a href='" + callbackUrl + "'>") + "</a>";

验证令牌

public async Task<bool> ConfirmEmailAsync(string userId, string code)
    {
        if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(code))
            return false;


        var user = await _userManager.FindByIdAsync(userId);

        if (user == null)
            return false;

        var result = await _userManager.ConfirmEmailAsync(user, code).ConfigureAwait(false);

        if (!result.Succeeded)
            result = await _userManager.ConfirmEmailAsync(user, WebUtility.UrlDecode(code)).ConfigureAwait(false);

        return result.Succeeded;
    }

令牌无效

下面的令牌被编码了两次,但我们会处理这种情况

CfDJ8HYrrpCgcr5GvrItPOWapXRy8WF8odd%252BVKuDup7buRsl1x4agRpfgQlEIPWiBqM0Wuilu9tCv5l%252B3lNaAb89%252Fi%252B4k0y%252FH0jdXAbabz0%252FXDGA0eUrmcKdIsDFNuXeyP5ezTVmTx8t0ky9xCTXaKLAfvTsCJviETk5Ag9JbUs3l3%252BnUon6fyYOHsslJI5VKLqhMM0Sm%252BW1EE%252B%252FPEJ%252BXcn%252FPS1My%252BI1lExuF1R1hFEZScEsUCG%252Bx%252BVIFB9bzs1IoLC%252Baw%253D%253D

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • sometimes says invalid token 是什么意思?解释清楚。
  • @TanvirArjel _userManager.ConfirmEmailAsync 在响应中返回无效令牌
  • 可能是token已经过期了!你检查过这个吗?
  • 好的!知道了!我遇到了类似的问题!这是由于在作为查询字符串发布时对令牌值进行了解码。你明白我在说什么了吗?
  • 我有同样的问题,我正在使用 HttpUtility.UrlEncode(code).Replace("%", "-") 和 HttpUtility.UrlDecode(code.Replace("-", "%" )),我想 WebUtility.UrlEncode 也是如此 :)

标签: c# asp.net asp.net-mvc .net-core asp.net-core-2.1


【解决方案1】:

这个问题似乎是基本的查询字符串相关问题。 您的问题中没有关于样本预期值和样本实际值的提示。因此,我将无法在这里为您提供确切的答案。但是下面两个是肯定会解决这个问题的指针。

可能有两个问题:

问题一:HtmlDecode/UrlDecode后原始Base-64没有恢复

这些标记被编码为 base 64 字符串,其中可能包含诸如“+”之类的字符。

它们被发送到服务器。

然后服务器尝试对该字符串执行 HtmlDecode 操作,以删除实际存在于原始 base 64 令牌中的字符。

例如'+' 被空字符串替换。

所以,WebUtility.HtmlDecode 之后生成的令牌是无效的。这就是您收到无效令牌错误的原因

How to check this ?可以调试看看HtmlDecode之后的值是什么,期望值是多少。如果它们不同,那么这就是根本原因。

问题 2:查询字符串格式不正确

查询字符串中的多个键值对使用“&”字符连接。 例如键1=值1&键2=值2

但有时它的编码版本 &amp;amp; 不是 &amp; 而是出现在查询字符串中。
例如键1=值1&键2=值2

如果是这种情况,.Net 服务器将无法正确解析查询字符串。

How to check this ? 您可以使用 QueryString 属性直接从 HttpContext 或 HttpRequest 读取原始查询字符串并检查是否是这种情况。如果是这样,那么您可以更改您的客户端以发送适当的查询字符串(更合乎逻辑且可维护)或编写一些代码以在服务器端更正它。

这些指针应该可以帮助您解决问题。

【讨论】:

    【解决方案2】:

    您的电子邮件确认请求将为您提供 userId 和您的私钥的响应,但您的令牌方法应该是不同的功能,如令牌刷新,您需要添加一些条件,如令牌是否已过期然后刷新令牌

    【讨论】:

    【解决方案3】:

    这可能不是完美的答案,但如果您只需要紧急修复并减少头痛,只需生成更短的无灾难令牌/代码。

        services.AddIdentity<ApplicationUser, ApplicationRole>(options => {
            options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
            options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
        }).AddDefaultTokenProviders()
        .AddEntityFrameworkStores<YourDbContext>();
    

    【讨论】:

      【解决方案4】:

      您应该在将确认码传递给_userManager.ConfirmEmailAsync(user, code).ConfigureAwait(false) 方法之前对其进行解码。

      您已对您在 callBackUrl 中使用的确认代码进行了 URL 编码;在尝试使用它之前,您应该使用WebUtility.UrlDecode(code) 对其进行解码。

      【讨论】:

        【解决方案5】:

        我认为用户创建过程花费了太多时间 在您点击确认之前 确保检查创建用户的数据库 检查确认电子邮件在 sql 表中是否为假

        【讨论】:

          【解决方案6】:

          你不需要使用身份服务器来解决这个问题。

          当用户注册时,在您的用户表中添加两列。一个用于验证,另一个用于 IsVerified。在验证令牌列中添加一个 Guid。然后生成带有此 Guid 的链接。当用户单击此链接时,您将获得控制器内的 Guid。然后让该用户使用此列,然后将 IsVerified 列设置为 true 并删除您的 Guid 列。现在您的用户已成功验证。

          【讨论】:

            【解决方案7】:

            如果您的编码代码最后包含“==”。即在 urlencode 或 base64 编码之后,如果代码像这样“cm9vdA==”出现。

            对此进行解码不会为您提供准确的编码字符串,并且会导致无效代码。

            因此,在生成令牌时,请检查编码值是否以“==”结尾。如果它确实生成了另一个令牌,那么问题将得到解决。

            【讨论】:

              猜你喜欢
              • 2020-08-16
              • 2020-11-08
              • 1970-01-01
              • 1970-01-01
              • 2023-04-04
              • 2016-08-06
              • 2018-12-07
              • 2021-04-03
              • 1970-01-01
              相关资源
              最近更新 更多