Sdk micro-channel micro-channel access directory access jssdk

Micro-channel access directory jssdk

 

Long time no write something, and recently did a little hand H5 project, which uses a micro letter jssdk.

A reference to the development of micro letter, I am sure that it is easy to think of micro-channel complex documents, I also encountered the same problem.

Access jssdk process is relatively tortuous, so here writing an article about record access procedures, also hope to provide a little help to everyone.

First, the micro-channel official document reader

First, we need access to micro-channel jssdk, then the first step is to read the micro-channel development of the document: https:? //Mp.weixin.qq.com/wiki t = resource / res_main & id = mp1445241432

Open this page in the menu bar on the left, then click on: micro-letter web development - micro-letter JS-SDK documentation .

After opening, we can see the micro-channel JS-SDK access explained.

Overview, I will not say more, we look at the use of direct steps.

Second, the micro-channel using procedure JSSDK

JSSDK micro-channel using the steps of the following five steps:

Step one: binding domain

Here we need to be logged in micro-channel public platform to enter the "number of public settings," the "feature set" in fill "JS interface security domain." Is this:

After clicking Settings, such an input box pops up:

Here, you will probably have doubts? Need to record domain name, which is how I do it? Do not worry, here in my home network through Jiaotong way to build a local development environment.

Network penetration Portal: https: //blog.csdn.net/RabitMountain/article/details/85298819

Well, we realized within the network penetration, then this txt file where we put it? The default access path is tomcat ROOT, throw directly into the like, but pay attention to delete the original stuff, or else will result in forwarding the request, and thus can not have access to this txt file as an example springmvc might use.

Step two: the introduction js file

I will not say this, the introduction of js files directly on your web page on the line

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

Step Three: Verify the configuration interface injection permission by config

This is the front page, we need to deal with html, the information Hey it is injected through wx.config (), or else it will not call other interfaces.

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

Guess you like

Origin www.cnblogs.com/my-yan/p/11904254.html
Recommended