Asp.net 核心电子邮件确认有时会显示 InvalidToken

我正在使用 asp.net 核心身份2.1,并且我遇到了电子邮件确认的随机问题,虽然电子邮件确认有时会显示结果。错误 = 无效标记。令牌也不会过期。


注意:我们正在使用多个服务器,并且我们还将密钥存储在一个位置,以便所有服务器都使用相同的密钥。


用于电子邮件确认的代码段。


电子邮件确认


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

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


呼啦一阵风
浏览 260回答 5
5回答

达令说

此问题似乎是与基本查询字符串相关的问题。您的问题中没有关于样本期望值和样本实际值的指针。因此,我无法在这里为您提供确切的答案。但下面两个是指针,它们肯定会解决这个问题。可能存在两个问题:问题 1:在 HtmlDecode/UrlDecode 之后,原始 Base-64 无法恢复这些令牌被编码为 base 64 字符串,其中可能包含“+”等字符。它们被发送到服务器。然后服务器尝试对此字符串执行 HtmlDecode 操作,以删除原始 base 64 令牌中实际存在的字符。例如,“+”被空字符串取代。因此,在 WebUtility.HtmlDecode 之后生成的令牌无效。这就是您收到无效令牌错误的原因How to check this ?您可以进行调试,并查看 HtmlDecode 后面的值和预期值。如果它们不同,那么这就是根本原因。问题 2:查询字符串格式不正确查询字符串中的多个键值对使用“&”字符连接。例如,key1=value1&key2=value2但有时,它的编码版本不是在查询字符串中出现的。例如,key1=value1&key2=value2&&amp;如果是这种情况,.Net 服务器将无法正确分析查询字符串。How to check this ?您可以使用从 HttpContext 直接读取原始查询字符串,也可以使用 QueryString 属性的 HttpRequest,并检查是否属于这种情况。如果是这样,那么您可以更改客户端以发送适当的查询字符串(更具逻辑性和可维护性),或者编写一些代码以在服务器端进行更正。这些指针应该可以帮助您解决问题。

梵蒂冈之花

您对电子邮件配置的请求将为您提供 userId 和您的私钥的响应,但您的令牌方法应该是不同的函数,如令牌刷新,您需要添加一些条件,例如如果令牌已过期,则刷新令牌

哈士奇WWW

如果编码的代码末尾包含“==”。即在urlencode或base64编码之后,如果代码像这样出现“cm9vdA==”。对此进行解码不会为您提供确切的编码字符串,并将导致无效代码。因此,在生成令牌时,请检查编码值是否以“==”结尾。如果它确实生成了另一个令牌,则问题将得到解决。

智慧大石

您不需要使用标识服务器来解决此问题。当用户注册时,请在用户表中添加两列。一个用于验证,另一个用于 IsVerified。在验证令牌列中添加一个 Guid。然后使用此 Guid 生成链接。当用户单击此链接时,您将在控制器中获取 Guid。然后使用此列获取此用户,然后将“已验证”列设置为 true 并删除 Guid 列。您的用户现在已成功验证。

慕运维8079593

在将确认代码传递到方法中之前,应对其进行解码。_userManager.ConfirmEmailAsync(user, code).ConfigureAwait(false)您已经对您在 callBackUrl 中使用的确认代码进行了 URL 编码;您应该在尝试使用它之前对其进行解码。WebUtility.UrlDecode(code)
打开App,查看更多内容
随时随地看视频慕课网APP