前几天,有渔老师去现场为一位朋友解决一个网站注册验证的问题。问题是这样的:在朋友的网站用邮箱注册后,系统会发一封邮件到邮箱,然后点击链接设置账号的初始化密码。如下图所示:
但我点击这个链接后,wordpress一直提示invalid key,也就是说key错误。因为是wordpress框架,从url的路由看,我就打开wp-login.php,然后查看其中的action rp。我直观感觉,应该是get url中的key跟数据库中的key值不相等导致的。所以,想进入系统的mysql一查究竟,但遗憾的是竟然没有mysql权限,我也不知道他的网站是让谁做的,估计是个外包吧。因为朋友是不懂技术的,很多事情问他也是一问三不知。没办法,哪就自己闷头搞吧。
外事不决问google,内事不决问baidu。我习惯性地打开baidu,输入:wordpress新用户注册 key无效。发现碰到类似问题的同行也不少,且看他们是如何解决的?他们的建议是:
编辑wp-includes文件夹中的pluggable.php文件,把变量$message里的>符合去掉。我照做了,发现还是不行的哦。所以,网上的东西,很多都得自己再实践下,否则是要被坑的。但到这一步,我更加确信是key的值出问题了。然后我又仔细看了下邮件发送过来的链接,发现这个链接有个问题。
这个链接里的&是&被转义后的值。那么,我在浏览器里输入时把&替换成&会怎样呢?发现竟然OK了,这时密码重置成功了。这样,问题就好办了,理论上,我只要修改pluggable.php,把&替换成&就可以了。$message的变量赋值如下:
$message .= ‘<‘ . network_site_url(“wp-login.php?action=rp&key=$key&login=” . rawurlencode($user->user_login), ‘login’) . “>\r\n\r\n”;
但问题是,我用htmlspecialchars_decode($message)处理也不行,用str_replace("&","&",$message)处理也不行。也就是说,这个&替换不成&。
我再看这$message变量,rp后面的&怎么没被转义,而$key后面的&却被转义了。所以,到这一步,我就怀疑是不是语句的顺序有问题?然后,我就把&key=$key放到($user->user_login)后面。然后,根据前面baidu的一些意见,顺便把<和>符合也去掉。这样,修改后的message如下:
$message .= network_site_url(“wp-login.php?action=rp&login=” . rawurlencode($user->user_login)."&key=$key", ‘login’) . “\r\n\r\n”;
问题就这样解决了。
总结:1,出现问题,问baidu一般都能找到一些建议。但这些建议不一定完全正确,自己还得根据实际情况修改。2,html的一些特殊符号,在存数据库之前需要被转义,在取出数据库后,需要被转换回来,这也是一个很重要的知识点。