記一次微信分享前後端實現

三隻萌新發表於2019-11-14

前言

在app端h5呼叫原生的分享功能,通過傳遞 title , desc,link 等引數可以自定義分享連結的樣式如下:

記一次微信分享前後端實現
當我們開啟分享後的頁面點選微信原生的分享後,會看到如下樣式的分享連結。確實有點醜,所以接下來我們來接入 微信JS-SDK 服務端通過node來請求微信服務來實現一次整體的分享過程。
記一次微信分享前後端實現

測試號管理

  1. 在這個頁面你會得到測試號資訊 appIDappsecret
  2. 需要驗證介面配置資訊,主要是為了驗證伺服器地址的有效性。
  3. JS介面安全域名,你需要使用微信 JS-SDK 的伺服器域名
  4. 測試號二維碼,掃碼後你的微訊號才有許可權使用 JS-SDK 的功能

具體流程可以點選檢視具體流程,重點說下第二點,驗證伺服器有效性。

記一次微信分享前後端實現

  1. URL:填寫上你服務端介面的地址
  2. Token:隨意填寫,在你服務端介面中會用到
  3. 微信會向你填寫的URL傳送一個請求並且帶上 signature,timestamp,nonce,echostr 引數,請求型別為 GET,我們接受到這些引數後需要進行加密然後返回加密後的值作為驗證。

接下來來寫介面。

// 需要引入 sha1 包來將字串轉化
const sha1 = require('sha1')
router.get('/',async ctx=>{
  // 與你填寫的 Token 保持一致
  const token = 'gwxtoken'
  const {
    signature,
    timestamp,
    nonce,
    echostr
  } = ctx.query
  // 進行字典排序加密
  let str = [token, timestamp, nonce].sort().join("");
  let sha = sha1(str)
  // 校驗微信加密簽名,如果來自微信將 echostr 原樣返回
  if (sha === signature) {
    ctx.body = echostr
  } else {
    ctx.body = "wrong"
  }
})
複製程式碼

服務端

獲取 access_token

請求微信 access_token 介面,引數如下,請求型別為 GET ,可以拿到 access_token 的值。

grant_type appid secret
填寫 client_credential 測試資訊的appID 測試資訊的appsecret

獲取 jsapi_ticket

請求微信 jsapi_ticket 介面,引數如下,請求型別為 GET,可以拿到 的值

access_token type
填寫 access_token 的值 填寫 jsapi
const request = require('request')
// 獲取 access_token 
router.get('/assess-token',async ctx=>{
  let result  = await request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appID&secret=appsecret')
  ctx.body = result
})

function getData(url){
  return new Promise((resolve,reject)=>{
    request(url,function(err,res,body){
      resolve(body)
    })
  })
}

// 獲取 jsapi_ticket
router.get('/share',async ctx=>{
  // 獲取客戶端傳遞過來的 access_token 和分享地址
  const {sessionKey,link} = ctx.request.query
  let noncestr = '201913' // 自定義
  let timestamp = Math.floor(Date.now() / 1000) // 當前時間單位為 秒
  let result = await getData('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='+sessionKey+'&type=jsapi')
  let tiket = JSON.parse(result).ticket 
  ctx.body = {
    noncestr,
    timestamp,
    signature:sha1('jsapi_ticket=' + tiket + '&noncestr=' + noncestr + '&timestamp=' + timestamp +'&url='+link)
  }
})
複製程式碼

需要注意:

  1. noncestr 為自定義,timestamp 單位為秒
  2. 這裡使用 request 作為 http 請求,
var request = require('request');
request('http://www.google.com', function (error, response, body) {
    // 列印值可以發現,body才是我們想要的 ticket 值
});
複製程式碼
  1. koa2 中 ctx.body 如果放在 包含非同步操作的回撥中,返回均為404,(還不是很懂是為啥),所以此處封裝了一個 Promise 這樣可以通過 await 的方式將程式碼執行同步化,ctx.body 可以拿到服務端返回的值。

客戶端

通過wx.config介面注入許可權驗證配置

呼叫服務端的介面 為了獲取服務端定義的 timestamp,nonceStr,signature 這三個值,這三個值需要保持和服務端同步

    wx.config({
        debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
        appId: 'AppId', // 必填,企業號的唯一標識,此處填寫企業號corpid
        timestamp:'timestamp', // 必填,生成簽名的時間戳
        nonceStr: nonceStr, // 必填,生成簽名的隨機串
        signature,// 必填,簽名,見附錄1
        jsApiList: ['onMenuShareTimeline', // 分享到朋友圈
        'onMenuShareAppMessage', // 分享給朋友
        'onMenuShareQQ',// 分享到QQ
        'onMenuShareWeibo',// 分享到騰訊微博
        'onMenuShareQZone'] // 必填,需要使用的JS介面列表,所有JS介面列表見附錄2
    });
複製程式碼

呼叫微信分享等介面

在需要自定義分享連結或其他 sdk 支援的功能可以通過 wx.ready 來初始化這些功能,拿分享功能作為例子,更多功能參考文件

wx.onMenuShareAppMessage({
  title: '', // 分享標題
  desc: '', // 分享描述
  link: '', // 分享連結,該連結域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
  imgUrl: '', // 分享圖示
  type: '', // 分享型別,music、video或link,不填預設為link
  dataUrl: '', // 如果type是music或video,則要提供資料連結,預設為空
  success: function () {
    // 使用者點選了分享後執行的回撥函式
  }
})
複製程式碼

最後

當你看到這個提示框時候,那麼你已經完成 sdk 配置 和服務端返回的 signature 的校驗。記錄了一次整體使用的過程,方便以後檢視

記一次微信分享前後端實現

相關文章