最近写的微信分享功能,调试一个签名就用了一天时间,主要还是微信的API有点难看得懂吧!主要是调用JS-SDK时,生成签名花费了很长时间调试,到最后才发现原来是原来是自己配置做错了。
先看看官方的JS-SDK使用步骤:
1、获取access_token(普通的access_token),通过access_token获取jsapi_ticket,主要注意的是,jsapi_ticket和access_token每一天都是有使用次数限制的,超时时间是7200s,所以在使用的时候需要保存到全局变量或者数据库或者是redis等,并且需要写一个定时器,在7200s后重新获取这两个值,刷新到保存的区域中;以下是我获取access_token的方法:
public AccessToken getAccessToken(@Context HttpServletRequest req, @Context HttpServletResponse resp) throws ClientProtocolException, IOException{
HttpSession httpSession = req.getSession();
AccessToken token = new AccessToken();
String url = ACCESS_TOKEN_URL;
JSONObject jsonObject = WeiXinUtil.doGetStr(url);//使用刚刚写的doGet方法接收结果
if(jsonObject!=null){ //如果返回不为空,将返回结果封装进AccessToken实体类
token.setToken(jsonObject.getString("access_token"));//取出access_token
token.setExpiresIn(jsonObject.getInt("expires_in"));//取出access_token的有效期
httpSession.setAttribute("access_token", token.getToken());
System.out.println("授权获取的token==="+jsonObject.getString("access_token"));
Contants.ACCESS_TOKEN=jsonObject.getString("access_token");
Contants.token_expires_in=jsonObject.getInt("expires_in");
}
return token;
}
2、获取jsapi_ticket的主要实现方法如下:
public void getJsapi_ticket(@Context HttpServletRequest req, @Context HttpServletResponse resp) throws ClientProtocolException, IOException{
String access_token=Contants.ACCESS_TOKEN;
System.out.println("access_token==="+access_token);
String url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
JSONObject jsonObject=WeiXinUtil.doGetStr(url);
System.out.println(jsonObject);
String ticket=jsonObject.getString("ticket");
Contants.JSAPI_TICKET=jsonObject.getString("ticket");
Contants.ticket_expires_in=jsonObject.getInt("expires_in");
}
在步骤1和2已经为签名准备好了jsapi_ticket,再来看看JS-SDK使用的步骤三:通过config接口注入权限验证配置,在这个步骤,需要几个参数是要和服务器保持一致的:
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳(由开发者生成) nonceStr: '', // 必填,生成签名的随机串 (由开发者生成) signature: '',// 必填,签名 *(接下来计算这一个值是关键步骤) jsApiList: [] // 必填,需要使用的JS接口列表 });
以下是生成JS-SDK配置文件所需要的参数的步骤和代码:
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
public WxParam getEncryptJsapiTicket(@Context HttpServletRequest req , @Context HttpServletResponse resp, @RequestParam("url") String url) throws UnsupportedEncodingException {
String ticket=Contants.JSAPI_TICKET;
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//随机生成的时间戳
String noncestr = CommonUtil.getRandomString(16);//生成的16位随机码
String url1=java.net.URLDecoder.decode(url.split("=")[1],"UTF-8");//在调用js的页面完整URL
String signature=getSignature(url1, timestamp, noncestr);//开始进行sha1签名
WxParam wxparam=new WxParam();
wxparam.setNonce(noncestr);
wxparam.setSignature(signature);
wxparam.setTimestamp(timestamp);
return wxparam;
}
步骤2. 对string1进行sha1签名,得到signature:
public static String getSignature(String url,String timeStamp,String nonceStr){
//所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
String signValue = "jsapi_ticket="+Contants.JSAPI_TICKET+"&noncestr="+nonceStr+"×tamp="+timeStamp+"&url="+url;
String signature =DigestUtils.sha1Hex(signValue);
return signature;
}
到这里,生成页面需要的参数步骤已经完成了,这个时候需要在页面初始化的时候调用这个方法,获取相关参数,填充到we.config中即可调用成功。如果在开发过程中遇到报错,可以看微信的api附录,每一个报错信息都有对应的说明:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
接下来是时候贴一下页面的代码啦!
看看我的分享效果: