开发环境
uniapp+springboot
跳转链路以及需要调用的接口
设置微信公众号js接口安全域名。路径:【设置与开发】-【账号设置】-【功能设置】

设置IP白名单。设置路径:【设置与开发】-【安全中心】

获取微信accesstoken
// 后端核心代码
public JSONObject getWechatAccesstoken(JSONObject jsonObject) {
// ?grant_type=client_credential&appid=APPID&secret=APPSECRET
String appid = jsonObject.getString("appid");
String secret = jsonObject.getString("appsecret");
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
log.debug("开始获取accesstoken==>{}", url);
String s = HttpUtil.doGet(url);
log.debug("获取accesstoken返回==>{}", s);
return JSONObject.parseObject(s);
}获取微信签名ticket
// 后端核心代码
public JSONObject getWechatTicket(JSONObject jsonObject) {
// https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
String accessToken = jsonObject.getString("accessToken");
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
log.debug("开始获取WechatTicket==>{}", url);
String s = HttpUtil.doGet(url);
log.debug("获取WechatTicket返回==>{}", s);
return JSONObject.parseObject(s);
}页面路径的签名
// 后端核心代码
public JSONObject genWechatJSAPIConfig(JSONObject jsonObject) {
// Wm3WZYTPz0wzccnW
String noncestr = SignatureGeneratorUtil.randomStr(16);
String ticket = jsonObject.getString("ticket");
// 1414587457
String timestamp = System.currentTimeMillis() / 1000 + "";
String requestUrl = jsonObject.getString("signLink");
String sign = SignatureGeneratorUtil.generateSignature(noncestr, ticket, timestamp, requestUrl);
JSONObject result = new JSONObject();
result.put("appId", "你的appid");
result.put("timestamp", timestamp);
result.put("nonceStr", noncestr);
result.put("signature", sign);
log.debug("wx.config返回的参数为==>{}", JSONObject.toJSONString(result));
return result;
}SignatureGeneratorUtil工具类
package com.myyidong.common.util;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* 微信的签名方法
*/
@Slf4j
public class SignatureGeneratorUtil {
// 生成签名字符串的方法
public static String generateSignature(String noncestr, String jsapiTicket, String timestamp, String url) {
// 将参数放入Map中
Map<String, String> params = new HashMap<>();
params.put("noncestr", noncestr);
params.put("jsapi_ticket", jsapiTicket);
params.put("timestamp", timestamp);
params.put("url", url);
log.info("params"+params.toString());
// 对参数按照字段名的ASCII码从小到大排序
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
// 按照key=value的格式拼接成字符串
StringBuilder sb = new StringBuilder();
for (String key : keys) {
sb.append(key).append("=").append(params.get(key)).append("&");
}
// 去除最后一个"&"
sb.deleteCharAt(sb.length() - 1);
// 对拼接后的字符串进行SHA-1签名
return sha1(sb.toString());
}
// SHA-1签名方法
private static String sha1(String input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
// 日志输出,无其他业务处理,可以使用其他方法代替
LogOutUtils.exceptionLogOut(e);
return null;
}
}
}
this.commonUtil.requestStandard(
'http://ip:port/genWechatJSAPIConfig',
data
).then(res => {
let data = res.data
jweixin.config({
debug: true,
appId: data.appId,
timestamp: data.timestamp,
nonceStr: data.nonceStr,
signature: data.signature,
// 需要使用的JS接口列表
jsApiList: ['wx-open-subscribe', 'wx-open-launch-weapp',
'updateTimelineShareData', 'chooseImage', 'previewImage'
],
// 开放标签,跳转小程序时必填
openTagList: ['wx-open-launch-weapp']
});
jweixin.ready(function() {
console.log("..1....");
});
jweixin.error(function(res) {
console.log("..2....", JSON.stringify(res));
});
})前端完整代码
<template>
<view>
<wx-open-launch-weapp id="launch-btn" appid="你的小程序appid" path="你的小程序路径以及拼接的参数" env-version="版本(开发、体验、线上)">
<script type="text/wxtag-template">
<style>
.open-img {
display: block;
margin: 0 auto;
width: 32px;
height: 32px;
}
</style>
<div>
<img class="open-img" src="http://ip:port/demo.png"></img>
</div>
</script>
</wx-open-launch-weapp>
</view>
</template>
<script>
import jweixin from '/jweixin-1.6.0.js'
export default {
data() {
return {
}
},
onLoad(option) {
//最好是在这里把当前网址传给后台进行签名
let data = {
ticket: 'HoagFKDcsGMVCIY2vOjf9jIL0_rbOLn3KgNhkj-xLej37bHNP2eeKTnjfMkK2LsXfBkCgmTy4jFsHrSBme2Rvg',
signLink: location.href.split('#')[0]
}
this.commonUtil.requestStandard(
'http://ip:port/genWechatJSAPIConfig',
data
).then(res => {
let data = res.data
jweixin.config({
debug: true,
appId: data.appId,
timestamp: data.timestamp,
nonceStr: data.nonceStr,
signature: data.signature,
// 需要使用的JS接口列表
jsApiList: ['wx-open-subscribe', 'wx-open-launch-weapp',
'updateTimelineShareData', 'chooseImage', 'previewImage'
],
// 开放标签,跳转小程序时必填
openTagList: ['wx-open-launch-weapp']
});
jweixin.ready(function() {
console.log("..1....");
});
jweixin.error(function(res) {
console.log("..2....", JSON.stringify(res));
});
})
},
methods: {
// 监听跳转
sucFun() {
console.log('跳转');
},
// 监听错误
errFun() {
console.log('失败');
},
}
}
</script>
<style>
.container {
display: block;
box-sizing: border-box;
padding: 30px;
width: 100%;
/* background-color: red; */
}
</style>注意事项
一定要保证jweixin.config方法通过签名校验,否则跳转按钮不显示!!!!
前端jweixin.config方法中的signLink获取到的链接地址的域名必须与公众号js接口安全域名保持一致,否则签名校验不通过!!!!
评论