微信小程式登入流程梳理總結

寒江水發表於2018-12-24

前言

寫部落格主要是用來總結、鞏固知識點,加深自己對這個知識點的理解。同時希望能幫助到有需要的人。如有不正確的地方。可以在評論區指出。你們的支援。是我不斷進步的源泉。

小程式登入流程

這裡引用下官方的一張登入流程圖,我就按照登入流程圖來講下我的理解。

alt

第一步

客戶端(小程式)獲取當前微信登入使用者的登入憑證(code)

可通過wx.login api獲得。這裡有地方需要注意

1.wx.login不會彈授權彈框

2.wx.login換取的code只能使用一次,如果需要新code只能重新呼叫wx.login介面

    wx.login({
        success:(res)=>{
            let code= res.code
        }
    })
複製程式碼

第二步

通過上一步獲得的臨時登入憑證傳給伺服器端獲取openid和session_key.伺服器端需要通過appid、appsecret、(這裡的資料可以從小程式管理後臺獲得)code(第一步獲取到的code)向微信服務端傳送請求獲取seeeion_key和openid。為了安全。建議將獲得的session_key加密後再傳給客戶端。

第三步

客戶端獲得加密後的登入態後把登入態存在本地以便後面進行業務請求。由於小程式中不存在cookie機制。所以可以把登入態儲存在storage中。

以上就是微信官方登入流程圖的一個大體過程。

但是在實際應用中可能要複雜點?我們接下來看。

登入態在實際應用中的維護

這裡看一下微信官方的說明

通過 wx.login 介面獲得的使用者登入態擁有一定的時效性。
使用者越久未使用小程式,使用者登入態越有可能失效。
反之如果使用者一直在使用小程式,則使用者登入態一直保持有效。
具體時效邏輯由微信維護,對開發者透明。
開發者只需要呼叫 wx.checkSession 介面檢測當前使用者登入態是否有效。
複製程式碼

這說明如果使用者一直在使用小程式。登入態就不會過期。反之就會過期。這裡可以通過wx.checkSession api 來判斷登入態是否過期。

接下來上程式碼。來看下在應用中的登入態維護。

目前在小程式中需要拉起微信登入授權的彈框。需要在wxml檔案中呼叫button元件來呼叫:如下

<button bindgetuserinfo="getInfo"  hover-class="none" open-type="getUserInfo"></button>
複製程式碼

這樣使用者點選按鈕的時候會彈出授權獲取使用者資訊的彈窗。使用者點選允許我們就可以拿到資料進行登入並進行業務請求。 如果點選拒絕可以獲取不需要登入可檢視的資料請求,並安利使用者拒絕後的結果。重新引導使用者進行授權。

下面是使用者非首次進入應用的一個登入態維護(首次進入通過button來授權。所以success回撥是不會執行的。直接fail的回撥。)

// 小程式啟動判斷使用者是否授權,根據是否授權來請求不同的業務資料
wx.getSetting({
  success: (res) => {
    //使用者已授權
    if (res.authSetting['scope.userInfo']) {
      // 判斷登入態是否過期
      wx.checkSession({
        // 登入態未過期,直接進行業務請求
        success: (res) => {
          //業務請求程式碼。。。
        },
        // 登入態已過期 。重新呼叫wx.login進行登入換取code
        fail: (res) => {
        // 可以在這裡進行重新登入後的回撥
          wx.login({
            success: function(res) {
              let code = res.code;
            }
          })
        }
      })
    }
    // 為授權 
    else {
      // 執行未授權的業務程式碼
    }
  }
})
複製程式碼

附上登入態過期的回撥。

  /**
   * 登入失敗後重新登入
   */
  getToken: function(fn) {
    let that = this;
    let getLogin = new Promise((resolve, reject) => {
      //登入獲取code
      wx.login({
        success: function(res) {
          var code = res.code;
          that.globalData.code = code;
          resolve([fn, code]);
        },
        fail: function(res) {
          reject();
        }
      })
    });
    getLogin.then(([fn, code]) => {
      return new Promise((resolve, reject) => {
        //使用該api需要在頁面通過button元件觸發授權彈窗
        wx.getUserInfo({
          success: function(res) {
            //這裡的iv,encryptedData等資料是用來伺服器端進行解密的。
            let requestData = {
              "Data": {
                "IV": res.iv,
                "EncryptedData": res.encryptedData,
                "JsCode": code,
              },
            }
            //傳送請求
            wx.request({
              url: that.apiList.login.getLogin,
              data: requestData,
              method: "POST",
              success: function(res) {
              //獲取到自定義登入態存入storage
                if (res.data && res.data.Success) {
                  that.globalData.token = res.data.Data.Key;
                  wx.setStorageSync('LoginSessionKey', res.data.Data.Key);
                  resolve(fn);
                } else {
                  reject();
                }
              },
              fail: function() {
                Hq.tipMaskNoneIcon('您的網路開小差了');
              }
            })
          }
       
        })
      });
    }).then((fn) => {
      that.getCountryInfo(fn);
    }, function() {}))
  },

  //執行fn回撥函式
  getCountryInfo: function(fn) {
    if (typeof fn == 'function') {
      //登入成功後進行業務請求。
      fn();
    } else {
      Hq.afterSend();
    }
  },
複製程式碼

以上就是我的一些理解。有語句不通,邏輯不清晰的地方,請不吝留言賜教!

感謝閱讀我的文章!

相關文章