微信公众号开发中,微信平台向第三方服务器转发的消息,在处理之前,是应该进行校验的。这一点,稍有安全常识的开发者都应该能意识到。然而,微信公众平台的接入指南中,只提到了一开始验证服务器时对 GET 请求的验证,而对 POST 请求的验证却只字不提,导致网上很多微信公众号开发的入门教程都忽略了这一点。微信平台向第三方服务器转发用户消息,都是以 POST 请求的方式进行的,如果不进行校验,可能被伪造(其实根本都不需要伪造好么)成微信平台的消息攻击。
微信公众平台的接入指南提到,GET 请求的校验,需要 token
、timestamp
、nonce
和 signature
,若
signature == sha1(sort(token, timestamp, nonce)) #这是伪代码
即为校验成功。其中 token
是开发者自己配置的,timestamp
、nonce
和 signature
是 URL 中携带过来的。校验算法可以自己实现,也可以用网上现成的代码,如 wechat_sdk 的 check_signature() 函数。Django 开发中,从 GET 请求的 URL 中获取后三个参数,可以用如下方法(以 signature
为例):
signature = request.GET.get('signature', None)
很多教程讲到这里就结束了,并不提 POST 请求如何验证,或者用了很繁琐的方法(如 WSGI)去提取 URL 中的参数。其实大可不必,POST 请求跟 GET 请求的验证方法完全一样,提取参数也是使用同样的语句:
signature = request.GET.get('signature', None)
注意了,虽然这是一条 POST 报文,但要从 URL 中提取 query string,还是得用 GET。就是这样。但是千万记得,一定要进行验证。