微信小程序受權登陸、解密unionId出錯

注:沒有在微信開放平臺作開發者資質認證的就不要浪費時間了,沒認證沒法獲取unionId,認證費用300元/年,emmmm....php

微信受權登陸流程

第一步:wx.login獲取 用戶臨時登陸憑證code前端

第二步:wx.getUserInfo獲取加密過的數據encryptedData和解密參數ivnode

第三步:把步驟1、二中的code、encryptedData、iv傳到開發者本身服務端python

第三步:服務端獲取到code、encryptedData、iv以後用get方法請求以下微信接口c++

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code小程序

appid:小程序appid
secret: 小程序密鑰
js_code: 第一步獲取的臨時登陸憑證code
grant_type:'authorization_code'
接口會返回 openid, session_key,注意:用戶已經受權過的平臺還會返回unionId,若是你只是須要unionId,則到此爲止api

官方文檔說法如圖:
官方文檔微信

沒有受權過則用encryptedData、session_key、iv、appid、secret進行解密,官方多語言解密示例下載連接:
unionId解密示例
包含c++ php python nodesession

第四步:仿照示例解密後得到unionId,想作什麼就作什麼了~app

如下是受權登陸前端代碼:

authLogin () {
    wx.login({
      success: loginRes => {
        let code = loginRes.code  // 獲取用戶臨時code
        wx.getUserInfo({
          success: function (res) {
            let encryptedData = res.encryptedData  // 獲取加密數據
            let iv = res.iv  //  解密參數
            // 發送解密必要數據到服務端
            wx.request({
              url: 'http://localhost',
              methods: 'POST',
              data: {
                code: code,
                encryptedData: encryptedData,
                iv: iv
              },
              succeess: res => {
                // 服務端首先調用微信接口獲取session_key
                // 用戶已經受權過的平臺會直接返回unionId
                // 沒有受權過則用session_key進行解密
                // 解密成功後服務端根據邏輯返回自定義信息
              }
            })
          }
        })
      }
    })
  }

以上步驟可行,可是微信調整了用戶受權方式

接口調整

新的受權需用button組件調用getUserInfo,因此在這以前沒法調用wx.login,可是若是先調用獲取用戶信息再調用wx.login的話,解密過程會出錯,猜想code對應的session_key和以前getUserInfo獲取的encryptedData不匹配

解決辦法:
在頁面的onLoad生命週期裏調用wx.login,獲取的code存入data以備須要的時候使用,可是code失效時間爲5分鐘,若是用戶停留頁面時間過長後點擊受權登陸,此時的code已通過期了,因此,獲取code的函數應該每4分鐘左右調用一次

wxml按鈕受權:
<button class="primary-bg" open-type='getUserInfo' bindgetuserinfo="authLogin">微信登陸</button>

js:

// 獲取code
  onLoad: function (options) {
    this.getCodeTimer()
  },
  getCodeTimer () {
    wx.login({
      success: res => {
        this.data.code = res.code
        setTimeout(() => {
          this.getCodeTimer()
        }, 4 * 60 * 1000)
      }
    })
  },
  // 受權登陸
  authLogin(event) {
    if (event.detail.errMsg == 'getUserInfo:ok') {
      wx.showLoading()
      let reqData = {
        code: this.data.code,
        encryptedData: event.detail.encryptedData,
        iv: event.detail.iv
      }
      wx.request({
        url: 'http://localhost:8080',
        methods: 'POST',
        data: reqData,
        success: (res) => {
          console.log(res)
            // 請求完成
        }
      })
    } else {
      console.log('用戶拒絕受權')
    }
  }

受權邏輯修改後實測沒有出過錯

相關文章
相關標籤/搜索