微信JSSDK配合Python+Tornado后端 运行通过

先看微信的JSSDK的运行结果

微信JSSDK配合Python+Tornado后端 运行通过
微信JSSDK配合Python+Tornado后端 运行通过

第一个弹框反馈config:ok表示已配置成功
第二个弹框反馈的是三个接口注册成功,分别是chooseImage,previewImage和chooseWXPay

微信公众号的JSSDK官方文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

建议从官方文档的第一篇教程往后基本都看完,我这里就是说主要的配置步骤和流程。

步骤一

微信公众号后台对JS接口安全域名进行配置

微信JSSDK配合Python+Tornado后端 运行通过

点击设置后,先下载这个MP_xxxxx.txt文件,然后放到项目的根目录下,让下图中的“域名1”中的填写的域名可以通过 telebytes.com/MP_xxxxx.txt 地址就能访问到
微信JSSDK配合Python+Tornado后端 运行通过
但是由于我们用的后端是Python+Tornado,所以txt文件是一个静态文件,它不能放在项目根目录下,只能放在static目录下,那么我们配置的域名总不能是这样吧 telabytes.com/static/ ,所以解决方案是把这个txt文件放到项目的static静态文件目录下,那项目的启动文件中的访问地址修改为
(r'/MP_xxxxx.txt', tornado.web.StaticFileHandler, {'path': "/static/xxxxx.txt"})

步骤二

获取Access Token

教程地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140183

https请求方式: GET

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

参数配置信息如下
微信JSSDK配合Python+Tornado后端 运行通过
使用网页调试工具调试该接口
https://mp.weixin.qq.com/debug/cgi-bin/apiinfo?t=index&type=基础支持&form=获取access_token接口%20/token

步骤三

JS-SDK使用权限签名算法,获取签名
1)、步骤二拿到Access_Token
2)、现在需要拿到jsapi_ticket

  ```
      // 访问此地址
	  https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
      
      // 返回
    	{
			"errcode":0,
			"errmsg":"ok",
			"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
			"expires_in":7200
		}
   ```

签名算法

import urllib3
import string
import random
import json
import hashlib

class WeChatAPI:

   def __init__(self): 
        # 特拉字节的微信公众号后台
        self.APP_ID = "你的微信APP ID"
        self.APP_SECRET = "你的APP SECRET"
        self.access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}".format(self.APP_ID, self.APP_SECRET)

        self.jsapi_ticket = None
        self.access_token = None
        
        
    def signature(self, current_url):
        # 获取access token
        access_token = self.get_access_token() 
        # 获取jsapi ticket
        jsapi_ticket = self.get_jsapi_ticket(access_token)
        # 在0-9 A-Z a-z里获取随机字符串
        noncestr = self.get_nonce_str()
        # 获取整型的时间戳
        timestamp = int(time.time())
        # 当前访问的页面的完整URL
        url = current_url
        parameters = {
            "noncestr" : noncestr,
            "jsapi_ticket" : jsapi_ticket,
            "timestamp" : timestamp,
            "url" : current_url 
        }
        # 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串
        unsinged_str = '&'.join(['{}={}'.format(key.lower(), parameters[key]) for key in sorted(parameters)])
        # 进行sha1签名,得到signature
        signedstr = hashlib.sha1(unsinged_str.encode("utf-8")).hexdigest()
        return signedstr, noncestr, timestamp, self.APP_ID


    def get_nonce_str(self):
        return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15))


    def get_access_token(self):
        resp_json = self.request_with_url(self.access_token_url) 
        self.access_token = _access_token
        expires_in = _expires_in
        return self.access_token


    def get_jsapi_ticket(self, access_token):
        jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={}&type=jsapi".format(access_token)
        resp_json = self.request_with_url(jsapi_ticket_url) 
        errcode = resp_json["errcode"]
        errmsg = resp_json["errmsg"]
        if errcode != 0:
            print("jsapi ticket获取失败!", errmsg)
            self.jsapi_ticket = None
            return None
        self.jsapi_ticket = resp_json["ticket"]
        expires_in = resp_json["expires_in"]
        return self.jsapi_ticket


    def request_with_url(self, url_str, method="GET"):
        http = urllib3.PoolManager()
        response = http.request(method, url_str)
        resp_json = json.loads(response.data)
        return resp_json

签名生成的规则验证页面
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

注意

1.签名用的url必须是当前页面的完整URL。微信公众号后台的“JS接口安全域名“为起始。
比如:当前访问的页面地址是:https://telabytes.com/xxx/xxx ,微信公众号后台配置的是 telabytes.com ,这就是正确的。
但是如果访问的地址是:https://www.telabytes.com/xxx/xxx ,微信公众号后台配置的是 telabytes.com ,这就是不对的,因为多了一个www的前缀

如果觉得以上签名太复杂,麻烦的话,就用以下这个Python的模块来进行签名,

from pywe_jssdk import jsapi_signature_params

def signature(self, current_url):
     parameters = jsapi_signature_params(self.APP_ID, self.APP_SECRET, current_url)
     return parameters["signature"], parameters["nonceStr"], parameters["timestamp"], parameters["appId"]

直接安装 pip install pywe-jssdk

步骤四

自己的页面中的JS代码配置如下
先在页面引入js地址:

<script src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

然后做jssdk的配置,上面在python tornado后台配置的代码做的签名等信息需要返回到页面上,因为wx.config需要用到

<input type="hidden" value="{{signedstr}}" id="signedstr" />
<input type="hidden" value="{{noncestr}}" id="noncestr" />
<input type="hidden" value="{{timestamp}}" id="timestamp" />
<input type="hidden" value="{{appId}}" id="appId" />

<script src="https://telabytes.com/static/assets/js/jquery-3.1.1.min.js"></script>
<script>
	var signedstr = $.trim($("#signedstr").val())
	var noncestr = $.trim($("#noncestr").val())
	var timestamp = $.trim($("#timestamp").val())
	var appId = $.trim($("#appId").val())
	wx.config({
		debug: true,
		appId: appId,
		timestamp: parseInt(timestamp),
		nonceStr: noncestr,
		signature: signedstr,
		jsApiList: [
			'checkJsApi',
			......
		    'chooseImage',
			'previewImage']
	   });

	wx.ready(function () {
	
		// 1 判断当前版本是否支持指定 JS 接口,支持批量判断
		wx.checkJsApi({
			jsApiList: [
				'chooseImage',
				'previewImage'
			],
			success: function (res) {
				json_res = JSON.stringify(res)
				alert(json_res);
			}
		});
		
	})
</script>

将页面和代码部署到服务器上之后,重新下nginx,然后等一分钟左右再次访问,即可看到以下提示框
微信JSSDK配合Python+Tornado后端 运行通过
微信JSSDK配合Python+Tornado后端 运行通过

教程:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

签名的pip模块
https://pypi.org/project/pywe-jssdk/
https://github.com/sdkwe/pywe-jssdk