微信網頁靜默授權

三隻萌新發表於2019-12-19

前言

使用者在微信客戶端中訪問第三方網頁,公眾號可以通過微信網頁授權機制,來獲取使用者基本資訊,進而實現業務邏輯。接下來了解下如何實現微信網頁靜默授權。

微信開發前配置

為了幫助開發者快速瞭解和上手微信公眾號開發,熟悉各個介面的呼叫,我們推出了微信公眾帳號測試號,通過手機微信掃描二維碼即可獲得測試號。 進入微信公眾帳號測試號申請系統

開發微信網頁授權功能必須有服務號(針對與企業),個人只能申請訂閱號。但是我們可以通過申請介面測試號來完成功能開發。

微信網頁靜默授權
開啟測試號管理頁面,提供的測試號資訊 appID 和 appsecret 。需要我們提供可用域名驗證伺服器資源可用。

具體做法就是:

  1. 在介面配置資訊中填寫你的伺服器地址,Token(自定義隨意寫)
  2. 微信服務會傳送一個請求給你的伺服器會帶上一系列引數,要求你返回對應的引數
// 服務端程式碼如下 
// 獲取 測試號管理微訊號 token
router.get('/token',async ctx=>{
  const token = 'customToken'
  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"
  }
})
複製程式碼

伺服器驗證成功後掃測試號二維碼新增使用者列表後就可以開始開發了。

開發步驟

投放連結格式

在服務號中投放連結格式如下(手動拼接的):

open.weixin.qq.com/connect/oau…

需要注意的是

  1. redirect_uri 地址的域名需要和 js介面安全域名對應。

  2. scope 應用授權作用域:snsapi_base (不彈出授權頁面,直接跳轉,只能獲取使用者openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到暱稱、性別、所在地。

通過 code 換取網頁授權 access_token

本身 redirect_uri 重定向的連結中是沒有 code ,當我們在微信瀏覽器中開啟投放的連結是,微信會自動跳轉到目標地址,並且在連結後拼接上 code 值。為了方便檢視,我將上面連結在微信開發者工具中開啟得到連結如下。

微信網頁靜默授權
客戶端獲取到連結中到 code 將其傳遞給服務端。服務端程式碼如下,呼叫 https://open.weixin.qq.com/connect/oauth2/authorize 並將相關引數傳遞給微信伺服器拿到 access_token

router.get('/access-token',async ctx=>{
  const grant_type = 'authorization_code'
  const code = ctx.query.code 
  // 拿到 access_token
  let wechatInfo = await fetchGet('/oauth2/access_token',{
    appid,
    secret,
    code,
    grant_type
  })
  console.log('wechatInfo',wechatInfo);
  // {"access_token":"28_pC4LZEoIa2boBlUlT2X3itT_yDAzrwiPXgqbxEAgf2XC7Eye2jHj3_WW4Xqf8ra0b-gPaCIC6bmiuS5O_VMQ4g","expires_in":7200,"refresh_token":"28_m5hfO9IYieZKJUCU7I_0LzJMdfFLmO10nX0IHiBEkW63yNTy2XBJS2wvke1uISSrKbsS9f3n7PpEjRRQgjl8CA","openid":"oNqRVxFO4TCF0CehAJfWGJI_kU14","scope":"snsapi_base"}
})
複製程式碼

獲取使用者資訊

如果 scope 為 snsapi_userinfo 在使用者授權了以後,會跳轉到 redirect_uri 的地址,服務端請求 connect/oauth2/authorize 介面後拿到 access_token 和 openid 。接下來通過這兩個引數去拉取使用者資訊。

const { access_token,refresh_token,openid } = wechatInfo
let userinfo = await fetchGet('/userinfo',{
  access_token,
  openid,
  lang:'zh_CN'
})
console.log('userinfo',userinfo);
// {"openid":"oNqRVxFO4TCF0CehAJfWGJI_kU14","nickname":"浼氶","sex":0,"language":"zh_CN","city":"","province":"","country":"","headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/QpnatTdwxlVfGO1ZdZYlACghRbXhq8sibI2GF8x0XhVqcmPKl7OQxI5wOobHiaiblOr0kaojXLGbicibc8pa8zk2wPg\/132","privilege":[]}
複製程式碼

校驗 access_token 是否有效 和 重新整理 access_token

通過該介面來判斷 access_token 的有效性

https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
複製程式碼

如需重新整理 access_token 將之前 /oauth2/access_token 介面返回的 refresh_token 作為引數去調重新整理的介面拿最新的介面

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
複製程式碼

"errcode":40163,"errmsg":"code been used

code說明 : code作為換取access_token的票據,每次使用者授權帶上的code將不一樣,code只能使用一次,5分鐘未被使用自動過期。

如果使用相同的 code 呼叫 connect/oauth2/authorize 介面後面會報這個錯誤。

注意點

如果使用者關注過公眾號後只需通過 openid 即可去拉取使用者的資訊

• 針對從公眾號入口進入的使用者採用靜默授權的方式

• 用法通過複製連結分享,或者二次分享的形式那麼獲得的使用者可能未關注過公眾號,想要拿到他們連結需要彈框授權。

code 無效情況

• 靜默授權後需要將連結中的code處理調否則會導致 code 重複使用造成無效的報錯。

    const url = location.href.replace(/code=\w+&/g,'')
        history.replaceState(history.state,document.title,url)
複製程式碼

二次分享link設定 需要跟微信後臺設定點安全域名列表中保持一致

• 二次分享時 link 無法直接分享 open.weixin.qq.com/... 的地址,其次的解決方式是,判斷連結中是否存在 code 如果不存在使用 location.href = url 的方式直接跳轉我們拼接好的 open.weixin.qq.com/... 但是會造成頁面一閃的情況,互動體驗不好。

• 引發的負作用就是如果一個頁面使用code授權到了第二個頁面,在第一個頁面已經將code處理掉,又會重新去通過 location.href 強刷一下頁面,這裡需要考慮使用 keep-alive 來處理。

• 連結中傳引數不穩定,如果在後續頁面新增引數在連結中由於 返回到首頁會導致頁面強制重新整理,可以考慮將引數存在本地

微信官方文件

相關文章