简要说明微信JS接口签名的生成方式
签名生成规则参与签名的字段包括有效的 jsapi_ticket(获取方式详见微信 JSSDK 文档), noncestr (随机字符串,由开发者随机生成),timestamp (由开发者生成的当前时间戳), url(当前网页的URL,不包含#及其后面部分。注意:对于没有只有域名没有 path 的 URL ,浏览器会自动加上 / 作为 path,如打开 http://qq.com 则获取到的 URL 为 http://qq.com/)。
对所有待签名参数按照字段名的 ASCII 码从小到大排序(字典序)后,使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 string1。这里需要注意的是所有参数名均为小写字符。
接下来对 string1 作 sha1 加密,字段名和字段值都采用原始值,不进行 URL 转义。即 signature=sha1(string1)。
示例noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com
对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com
附关键代码如下:
服务器端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@RequestMapping("/app1/index/**")
public String index(HttpServletRequest request, Model model){
SignPackage signPackage = new SignPackage();
signPackage.setAppId(properties.getCorpID());
String nonce_str = SignUtil.create_nonce_str();
String timestamp = SignUtil.create_timestamp();
signPackage.setNonceStr(nonce_str);
signPackage.setTimestamp(timestamp);
String url = getFullURL(request);
signPackage.setUrl(url);
String rawString = "jsapi_ticket=" + weixinUtil.getJsApiTicket() + "&noncestr=" + nonce_str + "×tamp=" + timestamp + "&url=" + url;
signPackage.setRawString(rawString);
String signature = SignUtil.getSignature(rawString);
signPackage.setSignature(signature);
model.addAttribute("signPackage", signPackage);
return "index";
}
前端:
wx.config({
debug: true,
appId: /*[[${signPackage.appId}]]*/ , // 必填,企业号的唯一标识,此处填写企业号corpid
timestamp:/*[[${signPackage.timestamp}]]*/, // 必填,生成签名的时间戳
nonceStr: /*[[${signPackage.nonceStr}]]*/, // 必填,生成签名的随机串
signature: /*[[${signPackage.signature}]]*/,// 必填,签名
jsApiList: ['onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'pauseVoice',
'stopVoice',
'onVoicePlayEnd',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'translateVoice',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'closeWindow',
'scanQRCode',
'openEnterpriseChat'] // 必填,需要使用的JS接口列表
});
调试工具
完成之后用微信提供的微信 JS 接口签名校验工具(见参考资料),测试下你的代码是否正确:
如:我用调试工具生成的签名为:
string1
jsapi_ticket=kgt8ON7yVITDhtdwci0qedLDDKuuDrvRIUFjARG8IV2iSprW5hisX7plWfW118kfjL5h9yCcVW3MZGmy4ehqmA&noncestr=0e88fc6a-7dab-432c-90c8-d4e538b2f854×tamp=1445916761&url=http://localhost:8030/app1/index
signature
c1d2af21d510d998310f79ace8254fac0ebb895a
对比在我本地打印出来的签名跟调试工具生成的签名是一致的,说明签名算法通过。
另外,在微信里面打开测试页面,显示:
{"errMsg":"config:ok"}
说明签名验证通过,你可以使用微信提供的jsapi了。
参考资料