微信分享
阿新 • • 發佈:2020-09-15
原理:
我們後臺將
noncestr(隨機32以內的字串)、
url(當前的url頁面,不包含#後面的,不要轉義url)、
jsapi_ticket(票據)、
timestamp(時間戳)
這幾個引數按首字母排序後用 & 拼接成鍵=值的形式,和get傳參一樣,拼接後得到一串字串,然後用 sha1 進行加密簽名,將這幾個引數(包含簽名後的 sign 字串)傳給前端,
前端將引數按照微信規則封裝成物件呼叫微信提供的 wx.config() 方法,微信會對這幾個引數和當前的url進行簽名驗證,如果驗證成功會呼叫 wx.ready() 方法
注意:
- 我前端使用的是 vue,所以url會有 # 號,我們傳給後端簽名的 url 是要獲取 當前 url # 號前面的部分
- 分享的圖片連結要使用絕對路徑
- 我們要保證 我們後端簽名的 url 和微信自動獲取的當前 url 要一致,這個是重中之重
- 當前分享頁面的域名一定要在 微信公眾號平臺有配置
程式碼開始
1. 配置公眾號安全域名,這個自行百度
2. 引入微信提供的 jssdk
// 以下兩個隨便引入一個即可
https://res.wx.qq.com/open/js/jweixin-1.6.0.js
https://res2.wx.qq.com/open/js/jweixin-1.6.0.js
3. 前端獲取當前的 url 當成引數請求後端簽名
// ajax 方法自己編寫,url 這樣獲取就行
url: location.href.split('#')[0]
4. 後端接收 url 後按照微信規則進行簽名返回
@GetMapping("/getShareOption") public R getShareOption(String url) {
// 獲取10位時間戳 String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
// 隨機字串,可自行設定,我這裡使用的是微信提供的依賴 String noncestr = WXPayUtil.generateNonceStr();
// 臨時票據,獲取這個票據需要先獲取微信的 accessToken, 這個百度一下,多的是答案 String ticket= weChatUtils.getTicket();
// 公眾號id, 微信公眾號平臺提供的 String appId = config.getWeChatAppId();
// 用 map 封裝 Map<String, String> map = new HashMap<>(); map.put("noncestr", noncestr); map.put("url", url); map.put("jsapi_ticket", ticket); map.put("timestamp", timeStamp); Set<String> keySet = map.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]);
// 排序, 這個是關鍵 Arrays.sort(keyArray); StringBuilder sb = new StringBuilder();
// 用 & 拼接鍵值對 for (String k : keyArray) { if (map.get(k).trim().length() > 0) // 引數值為空,則不參與簽名 sb.append(k).append("=").append(map.get(k).trim()).append("&"); } String str = sb.toString(); if(str.endsWith("&")){ str = str.substring(0, str.length() - 1); } log.info("簽名引數:{}", str); String signature = DigestUtils.sha1Hex(str); log.info("簽名後的值:{}", signature);
// 將這幾個引數 返給前端 return R.ok().put("appId", appId).put("timestamp", timeStamp).put("noncestr", noncestr).put("signature", signature); }
5. 前端接收到返回值後,呼叫 wx.config() 方法
// 微信一鍵分享引數 fetchWechatShareParams () { this.$http({ url: this.$http.adornUrl('/weChat/getShareOption'), method: 'GET', params: this.$http.adornParams({ url: location.href.split('#')[0] }) }).then(({ data }) => { let d = data.appId let i = data.timestamp let t = data.noncestr let n = data.signature
// 呼叫這個方法後,微信會驗證我們的簽名和微信的簽名是否一致,是則成功,否則失敗 window.wx.config({ debug: false, // 如果分享失敗,把0改成1開啟錯誤提示看看 appId: d, timestamp: i, nonceStr: t, signature: n, jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'] })
// 微信驗籤成功後才會呼叫這個方法 window.wx.ready(function () { window.wx.onMenuShareTimeline({ title: '分享標題', desc: '分享描述', link: '分享連結,這個不需要一定和當前的 url 一樣,有 # 沒問題,是一個完整可訪問的 url', imgUrl: '圖片地址,絕對路徑' }) window.wx.onMenuShareAppMessage({ title: '分享標題', desc: '分享描述', link: '分享連結,這個不需要一定和當前的 url 一樣, 有 # 沒問題,是一個完整可訪問的 url', imgUrl: '圖片地址,絕對路徑' }) }) }) }