微信接入 sdk 微信jssdk接入指南

微信jssdk接入指南

 

好久没有写点东西了,最近手里做了一个小小的H5项目,其中用到了微信jssdk。

一提到微信开发,大家肯定很容易想到微信那复杂的文档,我也遇到了同样的问题。

接入jssdk的过程是比较曲折的,所以在这里写一篇文章记录一下接入过程,也希望能够给大家提供一点帮助。

一、微信官方文档阅读

首先,我们要接入微信jssdk,那么第一步就是要阅读微信开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

打开这个网页,在左边的菜单栏,依次点击:微信网页开发 - 微信JS-SDK说明文档

打开之后,我们就可以看到微信JS-SDK接入说明了。

概述,我就不多说了,我们直接来看使用步骤。

二、微信JSSDK使用步骤

微信JSSDK使用步骤有以下五步:

步骤一:绑定域名

这里需要我们先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。也就是这样:

点击设置之后,弹出这样一个输入框:

这里,大家可能就会有疑问了?需要备案的域名,这我怎么办呢?别急,这里我交大家用内网穿透的方式,来搭建本地开发环境。

内网穿透传送门:https://blog.csdn.net/RabitMountain/article/details/85298819

好了,大家实现了内网穿透,那么这个txt文件我们放到哪里呢?tomcat的默认访问路径是ROOT,大家直接丢进去就好,但要注意把原来的东西删掉,要不然会因为示例中可能使用的springmvc造成请求转发,进而无法访问到这个txt文件。

步骤二:引入js文件

这个我也就不多说了,直接在你的网页里引入js文件就行

<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

步骤三:通过config接口注入权限验证配置

这个是前端html页面中需要我们处理的,就是通过wx.config()注入欸之信息,要不然就会无法调用其他接口。

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [] // 必填,需要使用的JS接口列表 }); 

这些东西,除了jsApiList,我们都需要从后端获取,那我们就向后台发起一个请求,然后后台封装一下返回给前端是不是就好了,很简单吧。

appId简单,直接从微信后台拿来用就行。

timestamp,后台直接生成就行,但要注意要以秒为单位。

nonceStr,java后台随便使用个uuid就可以了。

signature,这个有点东西啊,但也别急,微信有文档,我们慢慢看。

JS-SDK使用权限签名算法

在生成签名之前我们必须先了解一下jsapi_ticket。

jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。

步骤如下:

1. 获取access_token

我们据先获取access_token:思路很简单,就是我们用代码向微信服务器发一个请求,来换取它返回的access_token就行了。在写代码直接,我们还要添加ip白名单。这是因为微信规定,通过开发者ID及密码调用获取access_token接口时,需要设置访问来源IP为白名单。

添加了这个之后,我们来看一下代码:

WechatUtil.java

import com.alibaba.fastjson.JSONObject;

import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map; import java.util.UUID; public class WechatUtil { private static String appId = "xxxxxxxxxx"; private static String appSecret = "xxxxxxxxxxxxxxxxxxxx"; public static JSONObject getAccessToken() { String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appId=APPID&secret=APPSECRET"; String requestUrl = accessTokenUrl.replace("APPID", appId).replace("APPSECRET", appSecret); return WebUtil.doGet(requestUrl); } // 后面还有部分代码 } 

WebUtil.java

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; /** * Web相关工具类 */ public class WebUtil { /** * 发起http get请求 */ public static JSONObject doGet(String requestUrl) { CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String responseContent = null; JSONObject result = null; try { HttpGet httpGet = new HttpGet(requestUrl); response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); result = JSON.parseObject(responseContent); } catch (IOException e) { System.out.println("HTTP请求异常:" + e.getMessage()); } return result; } }

2. 用access_token换取jsapi_ticket

用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

{
    "errcode":0,
    "errmsg":"ok",
    "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }

这个就要我用access_token再向微信服务器发起请求,然后获得ticket就行了。但是,这个上面说了,调用次数有限,需要我们缓存,这里我们直接采用单例来缓存。

TokenSingleton.java

import com.alibaba.fastjson.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/** * 使用单例模式access_token全局缓存 */ public class TokenSingleton { private Map<String, String> map = new HashMap<>(); // 缓存accessToken的Map, map中包含一个accessToken和缓存的时间戳 private TokenSingleton() { } private static TokenSingleton single = null; public static TokenSingleton getInstance() { if (single == null) { single = new TokenSingleton(); } return single; } public Map<String, String> getMap() { String time = map.get("time"); String accessToken = map.get("access_token"); long nowDate = new Date().getTime() / 1000; if (accessToken != null && time != null && nowDate - Long.parseLong(time) < 5000 * 1000) { System.out.println("access_token存在,尚未超时,返回单例!"); } else { System.out.println("access_token超时或者不存在,重新获取!"); JSONObject jsonObject = WechatUtil.getAccessToken(); String newAccessToken = jsonObject.getString("access_token"); System.out.println("new access_token = " + newAccessToken); String jsApiTicket = getJsApiTicket(newAccessToken); map.put("time", nowDate + ""); map.put("access_token", newAccessToken); map.put("jsapi_ticket", jsApiTicket); } return map; } public String getJsApiTicket(String accessToken) { String apiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; String requestUrl = apiTicketUrl.replace("ACCESS_TOKEN", accessToken); System.out.println("getJsApiTicket.requestUrl ====> " + requestUrl); JSONObject result = WebUtil.doGet(requestUrl); System.out.println("getHsApiTicket.response ====> " + result); String jsApiTicket = null; if (null != result) { jsApiTicket = result.getString("ticket"); } return jsApiTicket; } } 

3. 签名

获得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?params=value
  1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
  1. 对string1进行sha1签名,得到signature:0f9de62fce790f9a083d5c99e95740ceb90c27ed

注意事项

  • 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  • 签名用的url必须是调用JS接口页面的完整URL。
  • 出于安全考虑,开发者必须在服务器端实现签名的逻辑。

总结来看,就是按顺序组装参数,用SHA-1加密一下就行了。当然,这里为了前后端交互,我们直接把所有需要的参数封装起来,到时候通过controller直接返回给前端。代码如下:

import com.alibaba.fastjson.JSONObject;

import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map; import java.util.UUID; public class WechatUtil { // 接上面的access_token获取代码 public static Map<String, String> generateWxTicket(String jsApiTicket, String url) { Map<String, String> ret = new HashMap<>(); String nonceStr = createNonceStr(); String timestamp = createTimestamp(); String string1; String signature = ""; string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url; System.out.println("string1 ====> " + string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); System.out.println("signature ====> " + signature); } catch (Exception e) { e.printStackTrace(); } ret.put("url", url); ret.put("jsapi_ticket", jsApiTicket); ret.put("nonceStr", nonceStr); ret.put("timestamp", timestamp); ret.put("signature", signature); ret.put("appid", appId); return ret; } /** * 字节数组转换为十六进制字符串 * * @param hash 字节数组 * @return 十六进制字符串 */ private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } /** * 生成随机字符串 * * @return 随机字符串 */ private static String createNonceStr() { return UUID.randomUUID().toString(); } /** * 生成时间戳 * * @return 时间戳 */ private static String createTimestamp() { return Long.toString(System.currentTimeMillis() / 1000); } } 

后台控制器

接下来我们用springmvc组装一个控制器,来接受前端的请求。

WechatController.java

import com.hbwomen.util.TokenSingleton;
import com.hbwomen.util.WechatUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/wechat") public class WechatController { @PostMapping("/config") @ResponseBody public Map<String, String> config(HttpServletRequest request) throws UnsupportedEncodingException { String signUrl = request.getParameter("signUrl"); Map<String, String> ret = new HashMap<>(); TokenSingleton tokenSingleton = TokenSingleton.getInstance(); Map<String, String> map = tokenSingleton.getMap(); String jsapi_ticket = map.get("jsapi_ticket"); // String newUrl = URLDecoder.decode(signUrl, "UTF-8"); ret = WechatUtil.generateWxTicket(jsapi_ticket, signUrl); return ret; } } 

完整前端代码

这里我们在补上前端的代码,就可以进行config了。

$(function () {
        var signUrl = window.location.href.split('#')[0]; $.ajax({ url: "/wechat/config", method: "post", data: { signUrl: signUrl }, success: function (data) { console.log("wx.config() ---> 接收后台返回的参数"); wx.config({ debug: true, appId: data.appid, timestamp: data.timestamp, nonceStr: data.nonceStr, signature: data.signature, jsApiList: ['onMenuShareAppMessage'] }) } }); });

步骤四:通过ready接口处理成功验证

wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

步骤五:通过error接口处理失败验证

wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
})

转自 https://www.cnblogs.com/xiaofeng-blog/p/10216988.html

好久没有写点东西了,最近手里做了一个小小的H5项目,其中用到了微信jssdk。

一提到微信开发,大家肯定很容易想到微信那复杂的文档,我也遇到了同样的问题。

接入jssdk的过程是比较曲折的,所以在这里写一篇文章记录一下接入过程,也希望能够给大家提供一点帮助。

一、微信官方文档阅读

首先,我们要接入微信jssdk,那么第一步就是要阅读微信开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

打开这个网页,在左边的菜单栏,依次点击:微信网页开发 - 微信JS-SDK说明文档

打开之后,我们就可以看到微信JS-SDK接入说明了。

概述,我就不多说了,我们直接来看使用步骤。

二、微信JSSDK使用步骤

微信JSSDK使用步骤有以下五步:

步骤一:绑定域名

这里需要我们先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。也就是这样:

点击设置之后,弹出这样一个输入框:

这里,大家可能就会有疑问了?需要备案的域名,这我怎么办呢?别急,这里我交大家用内网穿透的方式,来搭建本地开发环境。

内网穿透传送门:https://blog.csdn.net/RabitMountain/article/details/85298819

好了,大家实现了内网穿透,那么这个txt文件我们放到哪里呢?tomcat的默认访问路径是ROOT,大家直接丢进去就好,但要注意把原来的东西删掉,要不然会因为示例中可能使用的springmvc造成请求转发,进而无法访问到这个txt文件。

步骤二:引入js文件

这个我也就不多说了,直接在你的网页里引入js文件就行

<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

步骤三:通过config接口注入权限验证配置

这个是前端html页面中需要我们处理的,就是通过wx.config()注入欸之信息,要不然就会无法调用其他接口。

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [] // 必填,需要使用的JS接口列表 }); 

这些东西,除了jsApiList,我们都需要从后端获取,那我们就向后台发起一个请求,然后后台封装一下返回给前端是不是就好了,很简单吧。

appId简单,直接从微信后台拿来用就行。

timestamp,后台直接生成就行,但要注意要以秒为单位。

nonceStr,java后台随便使用个uuid就可以了。

signature,这个有点东西啊,但也别急,微信有文档,我们慢慢看。

JS-SDK使用权限签名算法

在生成签名之前我们必须先了解一下jsapi_ticket。

jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket。

步骤如下:

1. 获取access_token

我们据先获取access_token:思路很简单,就是我们用代码向微信服务器发一个请求,来换取它返回的access_token就行了。在写代码直接,我们还要添加ip白名单。这是因为微信规定,通过开发者ID及密码调用获取access_token接口时,需要设置访问来源IP为白名单。

添加了这个之后,我们来看一下代码:

WechatUtil.java

import com.alibaba.fastjson.JSONObject;

import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map; import java.util.UUID; public class WechatUtil { private static String appId = "xxxxxxxxxx"; private static String appSecret = "xxxxxxxxxxxxxxxxxxxx"; public static JSONObject getAccessToken() { String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appId=APPID&secret=APPSECRET"; String requestUrl = accessTokenUrl.replace("APPID", appId).replace("APPSECRET", appSecret); return WebUtil.doGet(requestUrl); } // 后面还有部分代码 } 

WebUtil.java

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import java.io.IOException; /** * Web相关工具类 */ public class WebUtil { /** * 发起http get请求 */ public static JSONObject doGet(String requestUrl) { CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse response = null; String responseContent = null; JSONObject result = null; try { HttpGet httpGet = new HttpGet(requestUrl); response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); result = JSON.parseObject(responseContent); } catch (IOException e) { System.out.println("HTTP请求异常:" + e.getMessage()); } return result; } }

2. 用access_token换取jsapi_ticket

用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

成功返回如下JSON:

{
    "errcode":0,
    "errmsg":"ok",
    "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }

这个就要我用access_token再向微信服务器发起请求,然后获得ticket就行了。但是,这个上面说了,调用次数有限,需要我们缓存,这里我们直接采用单例来缓存。

TokenSingleton.java

import com.alibaba.fastjson.JSONObject;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/** * 使用单例模式access_token全局缓存 */ public class TokenSingleton { private Map<String, String> map = new HashMap<>(); // 缓存accessToken的Map, map中包含一个accessToken和缓存的时间戳 private TokenSingleton() { } private static TokenSingleton single = null; public static TokenSingleton getInstance() { if (single == null) { single = new TokenSingleton(); } return single; } public Map<String, String> getMap() { String time = map.get("time"); String accessToken = map.get("access_token"); long nowDate = new Date().getTime() / 1000; if (accessToken != null && time != null && nowDate - Long.parseLong(time) < 5000 * 1000) { System.out.println("access_token存在,尚未超时,返回单例!"); } else { System.out.println("access_token超时或者不存在,重新获取!"); JSONObject jsonObject = WechatUtil.getAccessToken(); String newAccessToken = jsonObject.getString("access_token"); System.out.println("new access_token = " + newAccessToken); String jsApiTicket = getJsApiTicket(newAccessToken); map.put("time", nowDate + ""); map.put("access_token", newAccessToken); map.put("jsapi_ticket", jsApiTicket); } return map; } public String getJsApiTicket(String accessToken) { String apiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi"; String requestUrl = apiTicketUrl.replace("ACCESS_TOKEN", accessToken); System.out.println("getJsApiTicket.requestUrl ====> " + requestUrl); JSONObject result = WebUtil.doGet(requestUrl); System.out.println("getHsApiTicket.response ====> " + result); String jsApiTicket = null; if (null != result) { jsApiTicket = result.getString("ticket"); } return jsApiTicket; } } 

3. 签名

获得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?params=value
  1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value
  1. 对string1进行sha1签名,得到signature:0f9de62fce790f9a083d5c99e95740ceb90c27ed

注意事项

  • 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  • 签名用的url必须是调用JS接口页面的完整URL。
  • 出于安全考虑,开发者必须在服务器端实现签名的逻辑。

总结来看,就是按顺序组装参数,用SHA-1加密一下就行了。当然,这里为了前后端交互,我们直接把所有需要的参数封装起来,到时候通过controller直接返回给前端。代码如下:

import com.alibaba.fastjson.JSONObject;

import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map; import java.util.UUID; public class WechatUtil { // 接上面的access_token获取代码 public static Map<String, String> generateWxTicket(String jsApiTicket, String url) { Map<String, String> ret = new HashMap<>(); String nonceStr = createNonceStr(); String timestamp = createTimestamp(); String string1; String signature = ""; string1 = "jsapi_ticket=" + jsApiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url; System.out.println("string1 ====> " + string1); try { MessageDigest crypt = MessageDigest.getInstance("SHA-1"); crypt.reset(); crypt.update(string1.getBytes("UTF-8")); signature = byteToHex(crypt.digest()); System.out.println("signature ====> " + signature); } catch (Exception e) { e.printStackTrace(); } ret.put("url", url); ret.put("jsapi_ticket", jsApiTicket); ret.put("nonceStr", nonceStr); ret.put("timestamp", timestamp); ret.put("signature", signature); ret.put("appid", appId); return ret; } /** * 字节数组转换为十六进制字符串 * * @param hash 字节数组 * @return 十六进制字符串 */ private static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } /** * 生成随机字符串 * * @return 随机字符串 */ private static String createNonceStr() { return UUID.randomUUID().toString(); } /** * 生成时间戳 * * @return 时间戳 */ private static String createTimestamp() { return Long.toString(System.currentTimeMillis() / 1000); } } 

后台控制器

接下来我们用springmvc组装一个控制器,来接受前端的请求。

WechatController.java

import com.hbwomen.util.TokenSingleton;
import com.hbwomen.util.WechatUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/wechat") public class WechatController { @PostMapping("/config") @ResponseBody public Map<String, String> config(HttpServletRequest request) throws UnsupportedEncodingException { String signUrl = request.getParameter("signUrl"); Map<String, String> ret = new HashMap<>(); TokenSingleton tokenSingleton = TokenSingleton.getInstance(); Map<String, String> map = tokenSingleton.getMap(); String jsapi_ticket = map.get("jsapi_ticket"); // String newUrl = URLDecoder.decode(signUrl, "UTF-8"); ret = WechatUtil.generateWxTicket(jsapi_ticket, signUrl); return ret; } } 

完整前端代码

这里我们在补上前端的代码,就可以进行config了。

$(function () {
        var signUrl = window.location.href.split('#')[0]; $.ajax({ url: "/wechat/config", method: "post", data: { signUrl: signUrl }, success: function (data) { console.log("wx.config() ---> 接收后台返回的参数"); wx.config({ debug: true, appId: data.appid, timestamp: data.timestamp, nonceStr: data.nonceStr, signature: data.signature, jsApiList: ['onMenuShareAppMessage'] }) } }); });

步骤四:通过ready接口处理成功验证

wx.ready(function(){
    // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

步骤五:通过error接口处理失败验证

wx.error(function(res){
    // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
})

转自 https://www.cnblogs.com/xiaofeng-blog/p/10216988.html

猜你喜欢

转载自www.cnblogs.com/my-yan/p/11904254.html