微信企业号开发之获取jsapi_ticket并生成JS-SDK权限验证签名
2015-06-05 10:35
826 查看
在做企业号开发的时候,很有可能会调用微信提供的js接口(JS-SDK),
那么使用JS-SDK必须生成权限验证签名,而生成权限验证签名又必须依赖jsapi_ticket,
而获取jsapi_ticket又必须依赖AccessToken,在上一篇文章介绍了获取AccessToken的方法,
本章就介绍一下如何获取jsapi_ticket并且怎样生成JS-SDK权限验证签名。
注:以下内容摘自微信官方
jsapi_ticket
生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是企业号号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。
参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKE
成功返回如下JSON:
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的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
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
注:以上内容摘自微信官方
上一篇文章里面已经写了一个springMvc的Controller,这里我们在里面再添加两个方法,代码如下:
以上代码的getTsapiTicket方法用来获取jsapi_ticket,getJsSdkSign方法用来获取JS-SDK权限验证签名,在getJsSdkSign方法中有一个SignUtil类,用来生成签名,代码如下:
前台代码需要先获取jsapi_ticket,后生成JS-SDK权限验证签名,完整代码如下(包括之前生成AccessToken的代码):
那么使用JS-SDK必须生成权限验证签名,而生成权限验证签名又必须依赖jsapi_ticket,
而获取jsapi_ticket又必须依赖AccessToken,在上一篇文章介绍了获取AccessToken的方法,
本章就介绍一下如何获取jsapi_ticket并且怎样生成JS-SDK权限验证签名。
注:以下内容摘自微信官方
附录1-JS-SDK使用权限签名算法
jsapi_ticket生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是企业号号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。
参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKE
成功返回如下JSON:
{ "errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的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
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com
注:以上内容摘自微信官方
上一篇文章里面已经写了一个springMvc的Controller,这里我们在里面再添加两个方法,代码如下:
package com.weixin.qiye; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.weixin.utils.SignUtil; @Controller @RequestMapping("/qiye") public class QiyeController { private static final String CORPID="wxf75e84161068f7b7"; private static final String CORPSECRET="BkN0-Orh2d1GI9quC9GnG3KsmApLumgStJfmH29TzsekCWv4eO_8aR8KTZOVdOBh"; @RequestMapping("/getAccessToken") public void getAccessToken(HttpServletRequest request, HttpServletResponse response) throws Exception { String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+CORPID+"&corpsecret="+CORPSECRET; <span style="white-space:pre"> </span>processUrl(response, urlStr); } @RequestMapping("/getTsapiTicket") public void getTsapiTicket(HttpServletRequest request, HttpServletResponse response) throws Exception { String access_token = request.getParameter("access_token"); String urlStr = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token="+access_token; processUrl(response, urlStr); } @RequestMapping("/getJsSdkSign") public void getJsSdkSign(HttpServletRequest request, HttpServletResponse response) throws Exception { String noncestr = request.getParameter("noncestr"); String tsapiTicket = request.getParameter("jsapi_ticket"); String timestamp = request.getParameter("timestamp"); String url = request.getParameter("url"); String jsSdkSign = SignUtil.getJsSdkSign(noncestr, tsapiTicket, timestamp, url); PrintWriter out = response.getWriter(); out.print(jsSdkSign); } private void processUrl(HttpServletResponse response, String urlStr) { URL url; try { url = new URL(urlStr); URLConnection URLconnection = url.openConnection(); HttpURLConnection httpConnection = (HttpURLConnection)URLconnection; int responseCode = httpConnection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream urlStream = httpConnection.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlStream)); String sCurrentLine = ""; String sTotalString = ""; while ((sCurrentLine = bufferedReader.readLine()) != null) { sTotalString += sCurrentLine; } PrintWriter out = response.getWriter(); out.print(sTotalString); }else{ System.err.println("失败"); } } catch (Exception e) { e.printStackTrace(); } } }
以上代码的getTsapiTicket方法用来获取jsapi_ticket,getJsSdkSign方法用来获取JS-SDK权限验证签名,在getJsSdkSign方法中有一个SignUtil类,用来生成签名,代码如下:
package com.weixin.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; public class SignUtil { public static boolean checkSignature(String signature,String timestamp,String nonce){ String token="leonjo"; String[] array=new String[]{token,timestamp,nonce}; Arrays.sort(array); String content=array[0].concat(array[1]).concat(array[2]); String ciphertext=null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(content.toString().getBytes()); ciphertext=byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ciphertext!=null?ciphertext.equals(signature.toUpperCase()):false; } public static String getJsSdkSign(String noncestr,String tsapiTicket,String timestamp,String url){ String content="jsapi_ticket="+tsapiTicket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url; String ciphertext=null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(content.toString().getBytes()); ciphertext=byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ciphertext; } public static String byteToStr(byte[] byteArray){ String strDigest=""; for (int i = 0; i < byteArray.length; i++) { strDigest+=byteToHexStr(byteArray[i]); } return strDigest; } public static String byteToHexStr(byte mByte){ char[] Digit={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char[] tempArr = new char[2]; tempArr[0]=Digit[(mByte>>>4)&0X0F]; tempArr[1]=Digit[mByte&0X0F]; String s=new String(tempArr); return s; } }
前台代码需要先获取jsapi_ticket,后生成JS-SDK权限验证签名,完整代码如下(包括之前生成AccessToken的代码):
$.ajax({ dataType:"json", url: "http://leonjoweixin.duapp.com/weixingongzhong/qiye/getAccessToken", success: function(data){ $.getJSON("http://leonjoweixin.duapp.com/weixingongzhong/qiye/getTsapiTicket", { access_token:data.access_token //获取的access_token }, function(result){ var time=new Date().getTime(); $.get("http://leonjoweixin.duapp.com/weixingongzhong/qiye/getJsSdkSign", { noncestr:"Wm3WZYTPz0wzccnW", jsapi_ticket:result.ticket,//获取的jsapi_ticket timestamp:time, url:location.href.split('#')[0] }, function(sign){ console.log(sign) //生成的JS-SDK权限签名 } ); } ); }, error:function(XMLHttpRequest, textStatus, errorThrown){ } });
相关文章推荐
- 微信公众平台开发教程(二) 基本原理及消息接口
- 微信公众平台开发教程(一) 微信公众账号注册流程
- 微信开发公众号本地调试
- 微信系列研究之-手把手教你脱掉微信的外衣
- 仿微信侧滑删除SwipeListView实例
- 微信购物一周年发展研究报告
- 微信支付后台总是返回数据签名错误篇二
- 类似于微信通讯录的界面Demo
- SwipeListView 详解 实现微信,QQ等滑动删除效果
- 微信公众平台智能回复机器人后台开发
- 微信分享须知
- 从一个小程序明白new和delete的奇特现象
- Android 微信支付body参数不支持中文的问题
- 微信接入自定义开发
- 微信支付商户申请接入信息汇总【接入教程】
- 微信JS-SDK说明文档及常见问题处理
- 用微信分享又用微信支付问题
- 微信开发 没有认证过的服务号怎么办?微信提供了测试号(开通了认证过的服务号的功能)
- 仿微信摇一摇震动
- 用c#开发微信 (12) 微统计 - 阅读分享统计系统 2 业务逻辑实现