您的位置:首页 > 移动开发 > 微信开发

微信企业号开发之获取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权限验证签名。

注:以下内容摘自微信官方


附录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){
}
});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: