准备写个公众号做消息提醒的工具,,于是去了微信公众平台,准备用测试号接口试试。代码写的没问题,服务器也是已经部署了的。基本上所有问题都排查了还是显示配置失败。最后发现是请求头的问题
先列举一下需要注意的问题,看看你做到了没有,没有就先解决这些
- 必须使用https://或http://开头的地址(绑定域名)
- 地址必须支持80端口和443端口(网上找个网站扫描一下)
- Token要么是英文要么是数字,3位以上,随便搞个abcdefg都行
官网示例的代码也有点问题,直接返回的true,实际上要返回echostr的值
然后这块就有坑了!!!
注意返回的必须是echostr的值,且返回的请求头必须和微信官方能接受的一样,他们收的是 text/html; charset=utf-8
一开始我是用的django的rest_framework框架,返回的Response的结果,虽然我设置了content_type但是这块有个坑,仍要注意的就是,Response类的默认行为是传递给它的数字自动序列为JSON格式,并且内容类型默认application/json。所以即使我设置了content_type="text/html; charset=utf-8。返回的结果仍然是JSON格式的。下面粘贴一下报错的Django代码
from rest_framework.response import Response
from rest_framework.views import APIView
import hashlib
class WeChatSignatureView(APIView):
def get(self, request, *args, **kwargs):
received_signature = request.query_params.get("signature")
received_timestamp = request.query_params.get("timestamp")
received_nonce = request.query_params.get("nonce")
your_token = "your_token" # 替换为你的token
if self.check_signature(received_signature, received_timestamp, received_nonce, your_token):
echostr = request.query_params.get("echostr")
# 关键代码,虽然我指定了content_type但还是序列化了,没卵用
return Response(echostr, content_type="text/html; charset=utf-8")
else:
return Response("Invalid signature", status=403, content_type="text/plain")
def check_signature(self, signature, timestamp, nonce, token):
tmp_arr = [token, timestamp, nonce]
tmp_arr.sort()
tmp_str = ''.join(tmp_arr)
tmp_str = hashlib.sha1(tmp_str.encode()).hexdigest()
return tmp_str == signature
如果你想返回 HTML 内容,并且需要设置正确的内容类型为 text/html; charset=utf-8,你应该手动创建一个 HttpResponse 对象,而不是使用 DRF 的 Response。以下是正确的示例:
from django.http import HttpResponse
def get(self, request):
received_signature = request.GET.get("signature")
received_timestamp = request.GET.get("timestamp")
received_nonce = request.GET.get("nonce")
yue_token = 'yueyue'
if self.check_signature(received_signature, received_timestamp, received_nonce, yue_token):
# 返回时用Django的HttpResponse就不会序列化,指定这个content_type就能起到作用
return HttpResponse(request.query_params.get("echostr"), content_type="text/html; charset=utf-8")
else:
return Response("Invalid signature", status=403)
def check_signature(self, signature, timestamp, nonce, token):
tmp_arr = [token, timestamp, nonce]
tmp_arr.sort()
tmp_str = ''.join(tmp_arr)
tmp_str = hashlib.sha1(tmp_str.encode()).hexdigest()
return tmp_str == signature
最后终于大功告成