怎么實現無痛刷新token


最近遇到這個需求,前端登錄后,后端返回  access_token 和 refresh_token ,當token 過期時用舊的 refresh_token 去獲取新的token,前端要不痛去刷新token 並用新請求的token 去將用戶發送的請求執行完 並返回希望的數據。

我這里用的時axios 來實現,在攔截器中去做相應的處理axios.interceptors.response.use()方法。

首先說明一下,項目中的token是存在localStorage中的。

比如返回的一個狀態值時token過期的狀態  那我們將在這個狀態下去處理,如果時同時又多個請求發送過來的話  需要將請求存起來

當第二個過期的請求進來,token正在刷新,我們先將這個請求存到一個數組隊列中,想辦法讓這個請求處於等待中,一直等到刷新token后再逐個重試清空請求隊列。 那么如何做到讓這個請求處於等待中呢?為了解決這個問題,我們得借助Promise。將請求存進隊列中后,同時返回一個Promise,讓這個Promise一直處於Pending狀態(即不調用resolve),此時這個請求就會一直等啊等,只要我們不執行resolve,這個請求就會一直在等待。當刷新請求的接口返回來后,我們再調用resolve,逐個重試。

下面時我實現的代碼

let retryRequest = [] //存放token 過期的請求
let isRefresh = false // 是否在請求新的token

// HTTPresponse攔截
axios.interceptors.response.use(res => {
    const status = Number(res.status) || 200
    if (status === 401) {
    if (!isRefresh) {
      isRefresh = true
      return store.dispatch('RefreshToken',store.getters.refresh_token).then(data => {
       // 這里是去請求新的token 並返回promise 然后保存新的token
        store.commit('SET_ACCESS_TOKEN', data.data.access_token)
        store.commit('SET_REFRESH_TOKEN', data.data.refresh_token)
        res.config.headers['Authorization'] = data.data.access_token
        retryRequest.forEach(cb => {
          cb(data.data.access_token)
        })
        isRefresh = false
        retryRequest = []
        return axios(res.config)
      })
    }else {
      return new Promise((resolve) => {
        // 將resolve放進隊列,用一個函數形式來保存,等token刷新后直接執行
        retryRequest.push((token) => {
          res.config.headers['Authorization'] = token
          resolve(axios(res.config))
        })
      })
    }
  }

}

 第一次的請求沒有放到那個隊列中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM