{errcode“:-106,“errmsg“:“token check fail“} 微信公众号测试号接口配置报错Django版

准备写个公众号做消息提醒的工具,,于是去了微信公众平台,准备用测试号接口试试。代码写的没问题,服务器也是已经部署了的。基本上所有问题都排查了还是显示配置失败。最后发现是请求头的问题


先列举一下需要注意的问题,看看你做到了没有,没有就先解决这些

  • 必须使用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

最后终于大功告成
请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PENG越

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值