微信公众号开发Django-JSSDK授权
原文链接
上篇已经介绍过网页授权的基本操作,在进行网页开发的时候
也会遇到JSSDK授权的问题
警示:此JSSDK授权可能坑比较多~
如出现各种问题,可以到文末检查
部分代码上一篇文章已经提到解释,可以参考
另外如果出现非官方网页的提示,则不要在微信客户端调试
使用微信web开发者工具就可以了
获取ticket部分
此处官方文档明确提到用户需要缓存jsapi_ticket
因为其api调用次数非常有限,根据文档说明我把获取基础支持的acess_token和ticket写到了一起
代码如下
#xgc.wechat.py app_id=os.environ.get('APP_ID') app_secret=os.environ.get('APP_SECRET') #基础授权部分 base_get_access_token = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s'%(app_id,app_secret) get_ticket = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=' #views.py class base_authorization(): @classmethod def get_ticket(cls): key = 'ticket' if cache.has_key(key): ticket = cache.get(key) else: if cache.has_key('access_token'): access_token = cache.get('access_token') else: access_token = cls.get_access_token() from xgc.wechat import get_ticket ticket = requests.get(get_ticket+access_token).json()['ticket'] cache.set(key,ticket,110*60) return ticket @staticmethod def get_access_token(): from xgc.wechat import base_get_access_token key = 'access_token' access_token = requests.get(base_get_access_token).json()['access_token'] cache.set(key,access_token,110*60) return access_token
signature生成
首先我们signature生成需要一下几个参数noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)
其中官方提供了signature生成的python例子,如下的signature类,其中jsapi_ticket取自上方的ticket
class signature(View): def __init__(self,url): self.ret = { 'nonceStr': self.__create_nonce_str(), 'jsapi_ticket': base_authorization.get_ticket(), 'timestamp': self.__create_timestamp(), 'url': url } def __create_nonce_str(self): return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15)) def __create_timestamp(self): return int(time.time()) def sign(self): string = '&'.join(['%s=%s' % (key.lower(), self.ret[key]) for key in sorted(self.ret)]).encode('utf-8') self.ret['signature'] = hashlib.sha1(string).hexdigest() return self.ret
wx接口验证
# urls.py url(r'^activity', views.activity.as_view(), name='activity'), # views.py class activity(View): def get(self, request): return render(request, 'activaty.html') def post(self,request,*args, **kwargs): request_type = request.POST.get('type') if not request_type: request_body = json.loads(request.body.decode()) pathname = request_body['url'] sign = signature(unquote(pathname)) sign = json.dumps(sign.sign()) return HttpResponse(sign, content_type="application/json") elif request_type == 'image/jpeg': pass #传图片的时候会用到
首先我们先设置和前端进行交互的路由,然后我们利用下面的js进行wx初始配置
function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", '{{ csrf_token }}'); } }, }); //上方为Django-Ajax-CSRF设置 let wxStatus = 0 $(document).ready(function () { $.ajax({ type: 'POST', url: "http://test.flywinky.top/activity", // class activity设置的链接 data: JSON.stringify({ 'url': encodeURIComponent(location.href.split('#')[0]) }), headers: { 'Content-Type': 'application/json' }, success: function (res) { wx.config({ debug: false, appId: 'wx4f35679866a1b3a6', timestamp: res['timestamp'], nonceStr: res['nonceStr'], signature: res['signature'], jsApiList: ['chooseImage', 'uploadImage'] }) } }); wx.ready(function () { wxStatus = 1 }) wx.error(function (res) { wxStatus = 2 })
正常的情况如下图
然后就可以调用官方的各个接口了,只要你有相应的权限
接口列表在网页下方
Django-Ajax-CSRF
Django默认开启了CSRF验证
在进行Ajax请求POST的时候需要注意csrf_token的设置
官网文档这样写的
也可以按照我上方的代码,在html里
{% load static %} {{ csrf_token }} //就可以直接这样引入了
各种问题
首先推荐一篇帖子微信公众平台, config:invalid signature一直爆这个错误,求教如何解决?
官网文档总结:
invalid signature签名错误。建议按如下顺序检查:
- 确认签名算法正确,可用http://mp.weixin.qq.com/debug... 页面工具进行校验。
- 确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。
- 确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。
- 确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。
- 确保一定缓存access_token和jsapi_ticket。
- 确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
还有:
- 获取微信的jsapi_ticket有两个URL地址,一个是:https://api.weixin.qq.com/cgi...{0}&type=wx_card
另外一个是:https://api.weixin.qq.com/cgi...{0}&type=jsapi
第一个微信卡券的地址,应该是用第二个地址。
- 此处的access_token为基础支持的access_token,和网页授权的不同
- url在JavaScript中千万别忘记“encodeURIComponent”!否则后果很诡异,遇到过初始化的时候报invalid
signature,但是API接口又能调用的情况。
相关推荐
xiaonao00 2020-01-17
jieq 2020-11-09
ZZZhangbingyi 2020-08-26
haixianTV 2020-08-15
Develop 2020-06-25
郴州小程序 2020-06-13
huningjun 2020-06-12
zuoliangzhu 2020-06-11
hgzhang 2020-06-04
浪味仙 2020-06-03
powderhose 2020-06-02
cdkey 2020-05-29
戴翔的技术 2020-05-27
郴州小程序 2020-05-26
cdkey 2020-05-26
sucheng 2020-05-25
newhappy 2020-05-16
cbao 2020-05-12
cbao 2020-04-26