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

时间:2013-09-06 08:28:11

标签: html email url urldecode

[这可能不是一个编程问题,但这可能是程序员最好的答案。我首先在Pro网站管理员网站上尝试过,压倒性的沉默]

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

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解码它,解密它,并根据站点逻辑做适当的事情。

然而有时我们会有用户报告他们的点击无效。一位这样的用户向我们转发了他发送过的电子邮件,并且在检查时已经将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字符串 - 但没有其他百分比编码字符串 - 已被转换为加号。 (肯定是我们留下正确的值 - 我查看了相应的SMTP日志。)

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

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

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

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

  3. 如果是1 - 它是什么?在2的情况下 - 是否有一种标准的,已知的处理这种情况的方法?

    非常感谢您的帮助

2 个答案:

答案 0 :(得分:1)

问题在于此步骤

  

在检查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“key”不包含任何加号!

  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~'

答案 1 :(得分:0)

这里可能发生的是URLDecode正在将%2b转换为+,这被解释为URL中的空格字符。我能够通过首先对字符串进行urldecoding,然后使用replace函数用+字符替换已解码字符串中的空格,然后解密“固定”字符串来克服类似的问题。