第一步:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。备注:登录后可在“开发者中心”查看对应的接口权限。
第二步:引入js文件
在页面里引入微信的jssdk文件:http://res.wx.qq.com/open/js/jweixin-1.2.0.js
第三步:调用config接口注入权限
整体就是页面通过ajax请求后台生成签名,将生成的签名和生成签名时用的参数返回,在通过wx.config接口调用验证,这个验证大概就是微信拿到wx.config接口你配的参数也生成一个签名,然后和你生成的签名比较,一样验证成功,不一样验证失败。
前台:
$(function() {
var data = {};
data.htmlUrl = location.href.split('#')[0];
$.ajax({
url: SUrl+"/wechatUtils/getSignature",
type: 'post',
dataType: 'json',
contentType: "application/json;charset=utf-8",
data: JSON.stringify(data),
success: function(data) {
debugger
if(data.resCode == "200") {
wx.config({
debug:true,
appId: data.obj.appid,
timestamp: data.obj.timestamp,
nonceStr: data.obj.noncestr,
signature: data.obj.signature,
jsApiList: [
'scanQRCode'
]
});
}
},
error: function(jqXHR, textStatus, errorThrown) {
if(textStatus == "timeout") {
uTip.showDialog({
"tip_content": "连接超时,请检查网络"
});
} else {
uTip.showDialog({
"tip_content": "加载失败,请稍后再试"
});
}
}
});
wx.ready(function() {
wx.checkJsApi({
jsApiList: ['scanQRCode'],
success: function(res) {
if(res.checkResult.scanQRCode) {
return true;
} else {
mui.toast('您的设备不支持扫码!');
}
}
});
});
wx.error(function(res) {
mui.toast('初始化失败!');
});
});
wx.config验证成功会执行wx.ready里面的代码,我这里主要就是执行了wx.checkJsApi,这就是验证当前的设备是否支持扫二维码的功能。如果进入wx.error,就是wx.config验证失败了。具体的接口内容可以查看微信公众平台文档。
后台:controller
package com.xtpt.frontend.modules.wechat.web;
import java.util.HashMap;
import java.util.Map;
import com.lpcode.modules.dto.wechat.WxAccessTokenDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.framework.core.result.Result;
import com.framework.osp.common.utils.JedisClusterUtils;
import com.lpcode.modules.dto.wechat.WxJsapiTicketDto;
import com.lpcode.modules.dto.wechat.WxSignatureDto;
import com.lpcode.modules.dto.wechat.WxTemplateMessageDto;
import com.lpcode.modules.service.impl.wechat.WeChatUtilsServiceImpl;
import com.xtpt.frontend.util.wechat.WeChatUtils;
@Controller
@RequestMapping(value="/wechatUtils")
public class WxUtilsController {
private static final String NONCESTR = "szrq";
@Value("${wechat.appid}")
private String appid;
@Value("${wechat.appsecret}")
private String appsecret;
@ResponseBody
@RequestMapping(value="/getSignature" ,method = RequestMethod.POST,produces = "application/json;charset=UTF-8", consumes = "application/json;charset=UTF-8")
public Result<WxSignatureDto> getSignature(@RequestBody JSONObject requestObject){
Result<WxSignatureDto> result = new Result<WxSignatureDto>();
WxSignatureDto signatureDto = new WxSignatureDto();
String timestamp = (System.currentTimeMillis() / 1000) + "";
signatureDto.setTimestamp(timestamp);
signatureDto.setAppid(appid);
signatureDto.setNoncestr(NONCESTR);
String accessToken = WeChatUtils.getAccessToken(appid, appsecret).getAccesstoken(); //获取access_token
String jsapiTicket = WeChatUtils.getJsapiTicket(accessToken).getJsapiticket(); //获取jsapi_ticket
signatureDto.setSignature(WeChatUtils.getSignature(timestamp, NONCESTR, requestObject.getString("htmlUrl"), jsapiTicket)
result.setResCode("200");
result.setMsg("签名成功");
result.setObj(signatureDto);
return result;
}
}
签名时是需要jsapi_ticket的,这个值是调用微信接口获取的,这个接口入参需要access_token。
access_token是通过调用微信调口获取的,这个接口入参需要appid和appsecret(微信公众号里的基本配置里可以拿到)。
后台:WeChatUtils.getSignature()生成签名的方法
public static String getSignature(String timestamp, String nonceStr, String url, String jsapiTicket) {
MessageDigest md = null;
String string1 = "jsapi_ticket=" + jsapiTicket
+ "&noncestr=" + nonceStr + "×tamp=" + timestamp + "&url="
+ url;
String signature = "";
try {
md = MessageDigest.getInstance("SHA");
byte[] digest = md.digest(string1.getBytes());
signature = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return signature;
}
这个方法就是把timestamp, nonceStr,url,jsapiTicket拼接起来生一个SHA的签名,这里注意,这几个参数不是随便拼接的,是根据参数key首字母a-z拼接的,因为参数位置不一样生成的签名也是不一样的,我这里是正确的顺序。
后台:依赖方法
private static String byteToStr(byte[] digest) {
String strDigest = "";
for (int i = 0; i < digest.length; i++) {
strDigest = strDigest + byteToHexStr(digest[i]);
}
return strDigest;
}
第四步:config验证成功会执行ready
wx.ready(function(){
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});