小程序中實現token過期重新登錄再重新請求業務接口

簡介:

在微信小程序開發過程中,網絡請求是開發中最基礎也是最核心的需求,封裝一個穩定且可用性高的請求也顯得尤為重要。通常封裝的內容除了入參之外,更多的是請求中的異常處理。在處理 token 異常方面的做法,通過維護請求隊列,實現重發請求,減少 token 重復請求。

步驟:

  1. 正常業務請求
  2. 檢查該請求地址是否需要登錄后訪問,如果不需要,則直接訪問,該請求結束
  3. 如果需要,則判斷緩存Token是否存在,如果不存在,則直接跳轉登錄,如果存在,進入步驟4
  4. 請求后端接口,請求token未過期,則正常返回業務數據,如果請求token過期,則進入步驟5
  5. 調用Token刷新接口,刷新token過期,則直接跳轉登錄
  6. 刷新token沒有過期,則獲取token,并存入緩存 進入步驟7
  7. 在客戶無感知(無痛)情況下繼續請求最初的業務請求,將結果返回

需要注意:請求如果沒有限制處理,有多個請求同時到達,就會發起多個 updateToken 請求,其實我們并不想這樣,只需要請求一個updateToken即可,其他則直接排隊,等待第一個拿到后,直接使用

request1.js代碼

let isRefreshing = true; // 請求鎖
let pendings = []; // 請求列表
const pathArr = ['pages/buy-goods/index']; // 不需要登錄的路徑
const baseUrl = "http://192.168.0.112:9999";// 基礎路徑

function request({method, url, data, options = {
    needLogin: true
}}) {
    const token = wx.getStorageSync('tokenInfo')
    const pages = getCurrentPages();
    const router = pages[pages.length - 1]['route']; // 當前路由
    if (pathArr.includes(router)) options.needLogin = false; // 當前路徑是否需要登錄
    return new Promise((resolve, reject) => {
        // 需要登錄 但是 token不存在 跳轉登錄
        if (!token && options.needLogin) {
            wx.redirectTo({
                url: '/pages/login/login',
            })
            return
        }
        wx.showNavigationBarLoading();
        wx.showLoading({
            title: '數據加載中...',
            mask: true
        })
        // 請求主體
        wx.request({
            url: baseUrl + url,
            header:{
                Authorization:token.access_token
            },
            method,
            data,
            success(res) {
                let code = res.data.code
                if (code == '9898') {
                    resolve(res.data)
                } else if (code == '200') {
                    if (isRefreshing) {
                        updateToken();
                        isRefreshing = false;
                        pendings.push(() => {
                            resolve(request({method, url, data, options}))
                        })
                    }
                } else {
                    resolve(res.data);
                }
            },
            fail(err) {
                reject(err);
            },
            complete() {
                wx.hideNavigationBarLoading();
                wx.hideLoading();
            }
        })
    })
}
// 刷新token
function updateToken() {
    const token = wx.getStorageSync('tokenInfo');
    const userId = token.user_id;
    const refreshToken = token.refresh_token;
    wx.request({
        url: baseUrl + '/user/refreshToken',
        method: 'POST',
        data: {
            userId: userId,
            refreshToken: refreshToken
        },
        success(res) {
            let code = res.data.code
            if (code == '200') {
                wx.setStorageSync('tokenInfo', {
                    access_token: res.data.data.accessToken,
                    refresh_token: res.data.data.refreshToken,
                    user_id: res.data.data.userId,
                });
                pendings.map((callback) => {
                    callback();
                })
                isRefreshing = true;
            } else {
                toLogin();
            }
        }
    })
}
// 前往登錄頁面 清空狀態
function toLogin() {
    wx.showToast({
        title: '登錄失效,請重新登錄',
        icon: "none",
        success: () => {
            setTimeout(() => {
                wx.redirectTo({
                    url: '/pages/login/login',
                })
                pendings = [];
                isRefreshing = true;
            }, 1200);
        }
    })
}
module.exports = {
    request
};

業務js

import {
    request
} from '../../request/request1.js';
Page({

    /**
     * 頁面的初始數據
     */
    data: {

    },

    /**
     * 生命周期函數--監聽頁面加載
     */
    onLoad: function (options) {
        const orderId = options.orderId;
        this.queryOrderQuoteList(orderId);
    },

    async queryOrderQuoteList(orderId){
        const res = await request({
            method:"POST",
            url:"/order-quote/queryOrderQuoteList",
            data:{
            orderId: orderId,
            pageNum: 1,
            pageSize: 10
            }
        });
        console.log(res);
    }
})

效果

正常業務請求

刷新token

繼續請求業務
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容