1. 程式人生 > 其它 >多個請求,如何,無痛重新整理token

多個請求,如何,無痛重新整理token

同時多個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 }