为什么这个 %2B 字符串会被 urldecode ?

2024-01-04

[这可能不完全是一个编程问题,但它是一个最好由程序员来回答的难题。我首先在专业网站管理员网站上尝试过,结果一片寂静]

我们的网站上有电子邮件地址验证流程。该站点首先生成一个适当的密钥作为字符串

mykey

然后将该密钥编码为一堆字节

&$dac~ʌ����!

然后它对这串字节进行 Base64 编码

JiRkYWN+yoyIhIQ==

由于此键将作为要放置在 HTML 电子邮件中的 URL 的查询字符串值给出,因此我们需要首先对其进行 URLEncode,然后对结果进行 HTMLEncode,从而得到(在示例情况下 HTMLEncoding 没有任何效果,但是我懒得去修改这个例子)

JiRkYWN%2ByoyIhIQ%3D%3D

然后将其嵌入到作为电子邮件的一部分发送的 HTML 中,如下所示:

click <a href="http://myapp/verify?key=JiRkYWN%2ByoyIhIQ%3D%3D">here</a>. 
Or paste <b>http://myapp/verify?key=JiRkYWN%2ByoyIhIQ%3D%3D</b> into your browser.

当接收用户单击链接时,站点会接收请求,提取查询字符串“key”参数的值,对其进行 Base64 解码、解密,并根据站点逻辑执行适当的操作。

However有时,我们有用户报告他们的点击无效。一位这样的用户向我们转发了他发送的电子邮件,经检查,HTML 已转换为(用上面的示例表示)

click <a href="http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D">here</a>
Or paste <b>http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D</b> into your browser.

也就是说,%2B 字符串(但没有其他百分比编码字符串)已转换为加号。 (这绝对是leaving我们使用正确的值 - 我已经查看了相应的 SMTP 日志)。

key=JiRkYWN%2ByoyIhIQ%3D%3D
key=JiRkYWN+yoyIhIQ%3D%3D

所以我认为有以下几种可能性:

  1. 我正在做一些我看不到的愚蠢的事情,或者

  2. 一些邮件客户端将 %2b 字符串转换为加号,也许是为了解决人们错误地对加号进行 URLEncoding 的问题

如果是 1 - 它是什么?如果是 2 - 是否有一个标准的、已知的方法来处理这种情况?

非常感谢您的帮助


问题出在这一步

经检查,HTML 已转换为(用上面的示例表示)

click <a href="http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D">here</a>
Or paste <b>http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D</b> into
your browser.

也就是说,%2B 字符串 - 但没有其他百分比编码 字符串 - 已转换为加号

您在“另一端”的应用程序一定缺少转义步骤。无论是否有 %2B 还是 + 像 perls uri_unescape 这样的函数都会返回一致的答案

DB<9> use URI::Escape;
DB<10> x uri_unescape("JiRkYWN+yoyIhIQ%3D%3D")
0  'JiRkYWN+yoyIhIQ=='
DB<11> x uri_unescape("JiRkYWN%2ByoyIhIQ%3D%3D")
0  'JiRkYWN+yoyIhIQ=='

这是应该发生的事情。我所展示的只是步骤。我在调试器中使用 perl。步骤54将字符串编码为base64。步骤55展示了如何将base64编码的字符串制作成uri转义参数。步骤56和57是客户端应该执行的解码操作。

一种可能的解决方法是确保您的 base64“密钥”不包含任何加号!

  DB<53> $key="AB~"
  DB<54> x encode_base64($key)
0  'QUJ+
'
  DB<55> x uri_escape('QUJ+') 
0  'QUJ%2B'
  DB<56> x uri_unescape('QUJ%2B')
0  'QUJ+'
  DB<57> $result=decode_base64('QUJ+')
  DB<58> x $result
0  'AB~'
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这个 %2B 字符串会被 urldecode ? 的相关文章