微信小程序如何處理token過期問題

先說結論

業務流程:  從網絡日志中檢查到token過期,則跳轉到登錄頁面,要求用戶重新登錄。

代碼邏輯:使用自定義的HttpUtil封裝wx.request API,全局捕獲過期token並自動處理後,下發給上層業務。

問題

Token過期的現象:

在網絡請求中,客戶端token會過段時間過期,使得後續的網絡請求失敗,拋出異常日志如下:

data: {code: "99997", date: 1634174831325, message: "TOKEN EXPIRED", status: "ERROR"}

小程序提供的API: wx.request 是非常簡單,隻能在請求響應成功後的回調函數中開發者自己去檢查token過期,常規的做法:

1.定義檢查token過期的方法:

function checkAuth(resp) {
  if(resp.data.code == '99997') { //我們服務器返回的token過期的code是99997,code可以和後臺自定義。
    wx.navigateTo({
      url: '/pages/login/login', //這裡跳轉到登錄頁,要求用戶重新登錄
    })
    console.log("需要重新登錄......");
  }
}

2.在每個請求接口的響應中,調用checkAuth(res)去捕獲token過期。

問題代碼

function createMatchImage(data, fun) {
  //console.log(getApp())
  console.log("token = " + getApp().getToken())
  wx.request({
    method: 'POST',
    url: conf.baseUrl + 'match/matchImages', 
    data: data,
    header: {
      'content-type': 'application/json',
      'sessionKey': getApp().getToken()
    },
    success: function (res) {
      console.log(res)
      conf.checkAuth(res) // 判斷token是否過期,如果過期則跳轉到登錄頁。
      fun(res);
    }
  });
}
 
function getMatchImages(id, fun) {
  wx.request({
   ...
    success: function (res) {
      conf.checkAuth(res)
   ...
    }
  });
}
 
function deleteImage(id, fun) {
...
  wx.request({
    ...
    success: function (res) {
      conf.checkAuth(res)
      fun(res);
      //return res;
    }
  });
}

在上面的代碼中,每個接口都會有重復的代碼,如配置baseUrl,token,checkAuth()。所以這裡我們可以進一步去除重復代碼。

解決方案

統一網絡請求的入口,定義HttpUtil類。  封裝wx.request方法。

const get = (url, success, fail) => {
    var _token = getApp().getToken()
    wx.request({
      method:'GET',
      url: baseUrl + url,
      header:{
        'Authorization': _token,
        'content-type': 'application/json',
      },
      success:function(res) {
        checkAuth(res) // 在此處統一攔截token過期,跳轉到登錄界面
        console.log(res)
        success(res)
      },
      fail:function(res){
        console.log("請求失敗")
        fail(res)
      }
    })
}
···
 
module.exports = {
    get: get,
    post: post
}

HttpUtil的使用場景:

const httpUtil= require("../common/http/HttpUtil")
 
//邏輯層發起網絡請求,隻需要傳遞url和成功回調函數。這比以前更加簡潔。
function getActivities(success) {
    httpUtil.get('meetup/api/v1/activity/getActivityList?pageNo=1&pageSize=100', function(res) {
        success(res)
    })
}
 
module.exports = {
    getActivities : getActivities
}

如上,在使用httpUtil時, 處理token過期的過程是透明的 ,細節封裝到瞭內部。同時業務方也省去瞭設置token,token過期處理,baseUrl等樣板代碼。

使用Promise封裝回調函數

我們可以使用Promise,省去在調用請求接口時,傳入回調函數。

const get = (params) => {
    var _token = getApp().getToken()
    return new Promise((resolve, reject) => {
      wx.request({
        method:'GET',
        url: concatUrl(params),
        header:{
          'Authorization': _token,
          'content-type': 'application/json',
        },
        success: (res) => {
          checkAuth(res) // 在此處統一攔截token過期,跳轉到登錄界面
          resolve(res)
        },
        fail:(err) => {
          console.log("請求失敗")
          reject(err)
        }
      })
    })
}

使用方法:

// service層,定義網絡接口
function getActivities() {
    return HttpUtil.get({
        url: 'meetup/api/v1/activity/getActivityList?pageNo=1&pageSize=100'
    })
}
    /**
     * 加載活動列表(其中先加載群組以得到活動的頭像)
     */
    fetchGroupAndActivities: function(){
      if(this.data.isLogin) {
        var that = this
        getGroups() //先加載群組列表的頭像。
        .then((res)=>{
          if(res.data.code == "10000") { 
            ...
            return getActivities()  //其次,加載活動列表
          }
        })
        .then((res)=>{ //鏈式調用,處理活動列表數據。
          if (res.data.code == "10000") {
          ...
          }
        })
        .catch((err) => { //統一捕獲異常。 上面then中的任意回調發送異常,會直接中斷調用鏈,在這裡處理。
          console.log("get act and group failed...")
        })
    }},

總結

封裝過程wx.requestAPI中,在HttpUtil內部用Promise對象封裝baseUrl,token處理等,隱藏實現細節,對外提供統一接口和支持鏈式調用,這是常見的門面設計模式,缺點是違背瞭開閉原則,如果新增一些攔截請求接口處理,則要修改原有的接口實現。後續可加一個中間層,作為攔截器,用於擴展新功能。

到此這篇關於微信小程序如何處理token過期問題的文章就介紹到這瞭,更多相關小程序token過期內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: