web:
1、引入JS文件:
http://res.wx.qq.com/open/js/jweixin-1.4.0.js(支持https)
http://res2.wx.qq.com/open/js/jweixin-1.4.0.js (支持https)
2、获取签名等参数
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
service:
1、注册微信公众号,然后获取对应的appId和AppSecret,添加IP白名单和JS安全域名
2、获取access_token
https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
返回参数:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
7200秒access_token过期,所以记得一定缓存你的access_token
3、根据access_token获取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}
同样,7200秒jsapi_ticket过期,所以记得一定缓存你的jsapi_ticket
jsapi_ticket和access_token一定要是同时有效的,不然会出错
4、签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
随机字符串:
''.join(random.choice(string.ascii_letters + string.digits)for _in range(15))
时间戳:
int(time.time())
URL:
当前网页的完整URL,确保你获取用来签名的url是动态获取的,如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败
加上jsapi_ticket生成string1:
ret = {nonceStr=Wm3WZYTPz0wzccnWjsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qgtimestamp=1414587457url=http://mp.weixin.qq.com?params=value}
对所有待签名参数按照字段名的ASCII 码从小到大排序:
string ='&'.join(['%s=%s' % (key.lower(), ret[key])for key in sorted(ret)])
签名:(Python需要编码一次):
signature =hashlib.sha1(string.encode('utf8')).hexdigest()
这里就得到最终结果了,可用微信提供的工具进行校验
5、错误排查:
1.确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。
2.确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)://'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。
3.确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。
4.确保一定缓存access_token和jsapi_ticket。
5.确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。
Tip:大多数invalid signature是因为前段网页的URL和后端签名的URL不一样导致的,按照上文第5点进行确认
最后附上微信公众号开发官方文档