文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
后端生成签名,
获取jsapi_ticket:
拿到jsapi_ticket 传入当前页面的url
保证签名是正确的,url获取不包括hash的部分,是页面完整的url
@RestController
@RequestMapping("/jssdk")
public class JsSDKController {
static String jsapi_ticket;
static String appid ="wxed86c5b3295ef013";
static String secret="秘钥";
@Autowired
RestTemplate restTemplate;
@GetMapping("/hello")
public String hello(){
return "hello";
}
// @GetMapping("/sign")
// public Map<String, String> sign(String url){
// String jsapi_ticket = "jsapi_ticket";
// Map<String, String> ret = sign(jsapi_ticket, url);
// for (Map.Entry entry : ret.entrySet()) {
// System.out.println(entry.getKey() + ", " + entry.getValue());
// }
// return ret;
// }
@GetMapping("/sign")
private Map<String, String> getAccessToken(@RequestParam("url") String url){
String url1 = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
String formatUrl = String.format(url1, JsSDKController.appid, JsSDKController.secret);
HashMap map = restTemplate.getForObject(formatUrl, HashMap.class);
System.out.println("map = " + map);
Object accessToken = map.get("access_token");
System.out.println("accessToken = " + accessToken);
// 获取jsapi
String url2 ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
String ticketUrl = String.format(url2, accessToken);
System.out.println("ticketUrl = " + ticketUrl);
if (JsSDKController.jsapi_ticket == null){
HashMap map2 = restTemplate.getForObject(ticketUrl, HashMap.class);
Object ticket = map2.get("ticket");
System.out.println("ticket = " + ticket);
JsSDKController.jsapi_ticket = ticket.toString();
}else{
// 使用之前的ticket
}
Map<String, String> result = sign(JsSDKController.jsapi_ticket, url);
System.out.println("result = " + result);
return result;
}
public static void main(String[] args) {
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
String format = String.format(url, appid, secret);
System.out.println("format = " + format);
}
public static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
System.out.println(string1);
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
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;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>-->
<!--<script src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>-->
<script src="https://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
</script>
<button onclick="share()" >share</button>
<button onclick="open()">open </button>
<script>
async function fetchData() {
let {data:res} = await axios.get("/dev-api/jssdk/sign", {
params: {
url: location.href.split("#")[0] // 微信会统计次数,,,后面会有一些hash location.href
}
})
console.log(res,"res")
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'wxed86c5b3295ef013', // 必填,公众号的唯一标识
timestamp: res.timestamp, // 必填,生成签名的时间戳
nonceStr: res.nonceStr, // 必填,生成签名的随机串
signature: res.signature,// 必填,签名
jsApiList: ["chooseImage","onMenuShareAppMessage","onMenuShareTimeline","updateAppMessageShareData"] // 必填,需要使用的JS接口列表
});
wx.ready(function () { //需在用户可能点击分享按钮前就先调用
wx.updateAppMessageShareData({
title: 'hehe', // 分享标题
desc: '123', // 分享描述
link: 'http://water-kid.cn', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'http://water-kid.cn/favicon.ico', // 分享图标
success: function () {
// 设置成功
console.log("分享成功")
}
})
})
}
fetchData()
</script>
</body>
</html>