多個請求,如何,無痛重新整理token
阿新 • • 發佈:2022-03-13
同時多個axios請求怎麼實現無痛重新整理token
原文地址
https://blog.csdn.net/weixin_45178716/article/details/103286459
下面是程式碼細節
import axios from 'axios' import { Loading, Message, MessageBox } from 'element-ui' import api from './api' import { getToken, setToken, removeToken, getRefreshToken } from '../utils/cookies' let UserModule = { RefreshToken: (data) => { setToken('Bearer ' + data.access_token, data.refresh_token) } } // 是否正在重新整理的標記 let isRefreshing = false // 重試佇列,每一項將是一個待執行的函式形式 let retryRequests = [] const request = axios.create({ baseURL: api.baseUrl, timeout: 50000, withCredentials: true // cookie跨域必備 }) // http request 攔截器 Request request.interceptors.request.use( (config) => { if (getToken()) { config.headers['Authorization'] = getToken() } return config }, (error) => { Promise.reject(error) } ) // http response 攔截器 Response request.interceptors.response.use( (response) => { // code == 0: 成功 const res = response.data if (res.code !== 0) { if (res.message) { Message({ message: res.message, type: 'error', duration: 5 * 1000 }) } return Promise.reject(res) } else { return response.data } }, (error) => { if (!error.response) return Promise.reject(error) // 根據refreshtoken重新獲取token // 5000系統繁忙 // 5001引數錯誤 // 1003該使用者許可權不足以訪問該資源介面 // 1004訪問此資源需要完全的身份驗證 // 1001access_token無效 // 1002refresh_token無效 if (error.response.data.code === 1004 || error.response.data.code === 1001) { const config = error.config if (!isRefreshing) { isRefreshing = true return getRefreshTokenFunc() .then((res) => { // 重新設定token UserModule.RefreshToken(res.data.data) config.headers['Authorization'] = getToken() // 已經重新整理了token,將所有佇列中的請求進行重試 // @ts-ignore retryRequests.forEach((cb) => cb(getToken())) // 重試完清空這個佇列 retryRequests = [] // 這邊不需要baseURL是因為會重新請求url,url中已經包含baseURL的部分了 config.baseURL = '' return request(config) }) .catch(() => { resetLogin() }) .finally(() => { isRefreshing = false }) } else { // 正在重新整理token,返回一個未執行resolve的promise return new Promise((resolve) => { // 將resolve放進佇列,用一個函式形式來儲存,等token重新整理後直接執行 // @ts-ignore retryRequests.push((token: any) => { config.baseURL = '' config.headers['Authorization'] = token resolve(request(config)) }) }) } } else if (error.response.data.code === 1002) { resetLogin() } else { Message({ message: error.response.data.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } } ) // 重新整理token的請求方法 function getRefreshTokenFunc() { let params = { refresh_token: getRefreshToken() || '' } return axios.post(api.baseUrl + 'auth-center/auth/refresh_token', params) } function resetLogin(title = '身份驗證失敗,請重新登入!') { if (window.location.href.indexOf('/login') === -1) { MessageBox.confirm(title, '退出', { confirmButtonText: '重新登入', cancelButtonText: '取消', type: 'warning' }).then(() => { removeToken() location.reload() // To prevent bugs from vue-router }) } } /** * []請求 * @param params 引數 * @param operation 介面 */ function customRequest(url: string, method: any, data: any) { // service.defaults.headers['Content-Type']=contentType let datatype = method.toLocaleLowerCase() === 'get' ? 'params' : 'data' return request({ url: url, method: method, [datatype]: data }) } export { request, customRequest }