为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
呼啦一阵风 2022-08-20 17:36:48
我正在使用 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任何帮助将不胜感激,谢谢!
查看完整描述

5 回答

?
达令说

TA贡献1821条经验 获得超6个赞

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

可能存在两个问题:

问题 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,并检查是否属于这种情况。如果是这样,那么您可以更改客户端以发送适当的查询字符串(更具逻辑性和可维护性),或者编写一些代码以在服务器端进行更正。

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


查看完整回答
反对 回复 2022-08-20
?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

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


查看完整回答
反对 回复 2022-08-20
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

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

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

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


查看完整回答
反对 回复 2022-08-20
?
智慧大石

TA贡献1946条经验 获得超3个赞

您不需要使用标识服务器来解决此问题。

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


查看完整回答
反对 回复 2022-08-20
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

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

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


查看完整回答
反对 回复 2022-08-20
  • 5 回答
  • 0 关注
  • 259 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信