/ ThinkPHP

Thinkphp中使用支付宝接口同步返回Sign验证失败原因分析

今天给一套Thinkphp开发的程序集成支付宝接口时发现了很奇怪的现象,通过用户浏览器的同步返回到网站时提示Sign验证失败,但是支付宝的服务器异步返回却是正确的。

于是看了下支付宝SDK中同步返回的Sign验证部分,步骤如下:

1.获取$_GET中key为不为sign、sign_type并且value不为空的项

2.将新生成的数组按照key的ascii值进行排序(使用ksort函数)

3.把数组所有元素,按照“key=value”的模式用“&”字符拼接成字符串

4.把这个字符串和支付宝的安全验证码(配置中的“key”这一项)拼接,并计算md5

5.将计算出的md5值与$_GET[‘sign’]比较,如果相同则Sign验证通过

也就是说,Sign验证失败的原因就在于$_GET数组拼接成字符串过程

于是找了条同步返回的日志,因为是GET方式返回的,所以所有参数都有记录,通过上述方式计算md5,结果发现和支付宝服务器返回的md5是一致的,大概就可以猜出是Thinkphp对$_GET数组的改造导致的

在代码中将$GET数组输出,发现多了一项_URL,这是使用Thinkphp的pathinfo模式导致,可以通过$_GET[‘URL’]来获取url信息。

而支付宝服务器异步返回却没有这个问题,是因为异步返回使用的是POST方式,验证的也是$_POST数组,Thinkphp对$_GET的改造不影响到Sign验证。

所以解决方案是在进行Sign验证之前将$_GET中的_URL_删除,unset($_GET[‘URL’])

Thinkphp中使用支付宝接口同步返回Sign验证失败原因分析
Share this