http请求刷新token机制重构(待观察)

This commit is contained in:
bob
2024-09-13 22:10:50 +08:00
parent 5c92291f65
commit a2ec6d4648
3 changed files with 7 additions and 64 deletions

1
.gitignore vendored
View File

@@ -29,3 +29,4 @@ coverage
*.tsbuildinfo
note.md
*.bak

View File

@@ -17,6 +17,7 @@ export const userStore = defineStore(
secret: '',
expiretime: 0
})
// 注意这个是异步的取到的token一定是有效期内的
const getAccessToken = async () => {
const now = new Date().getTime()
if (at.value.expiretime && now < at.value.expiretime) {

View File

@@ -3,7 +3,6 @@ import { userStore } from '@/stores'
import router from '@/router'
import CryptoJS from 'crypto-js'
import { v4 as uuidv4 } from 'uuid'
import { CLIENT_TYPE, CLIENT_NAME, CLIENT_VERSION } from '@/const/userConst'
const baseURL = '/api' //配合vite.config.js中的代理配置解决跨域问题
@@ -23,7 +22,7 @@ const generateSign = (key, content) => {
// 请求拦截器
instance.interceptors.request.use(
(config) => {
async (config) => {
const userData = userStore()
if (config.url === '/user/refreshToken' && userData.rt.token !== '') {
const traceId = uuidv4()
@@ -34,13 +33,14 @@ instance.interceptors.request.use(
config.headers.sign = sigh
config.headers.refreshToken = userData.rt.token
} else if (userData.at.token !== '') {
const token = await userData.getAccessToken()
const traceId = uuidv4()
const timestamp = Math.floor(new Date().getTime() / 1000)
const sigh = generateSign(userData.at.secret, `${traceId}${timestamp}`)
config.headers.traceId = traceId
config.headers.timestamp = timestamp
config.headers.sign = sigh
config.headers.accessToken = userData.at.token
config.headers.accessToken = token
}
return config
},
@@ -59,9 +59,8 @@ instance.interceptors.response.use(
},
async (err) => {
if (err.response?.status === 403) {
// 403表示访问禁止由于AccessToken过期导致所以凡是403请求均刷新token后重发
const retryRes = await refreshTokenAndRetry(err.config)
return Promise.resolve(retryRes)
// 403表示访问禁止由于AccessToken或RefreshToken过期导致
ElMessage.error('会话过期,请退出后重新登录')
} else if (err.response?.status === 401) {
// 401错误返回登录页
router.push('/login')
@@ -74,63 +73,5 @@ instance.interceptors.response.use(
}
)
let isRefreshing = false
let requestsQueue = []
const refreshTokenAndRetry = (config) => {
const userData = userStore()
const traceId = uuidv4()
const timestamp = Math.floor(new Date().getTime() / 1000)
const sigh = generateSign(userData.rt.secret, `${traceId}${timestamp}`)
return new Promise((resolve, reject) => {
if (isRefreshing) {
requestsQueue.push({ resolve, reject, config })
} else {
isRefreshing = true
axios
.post(
'/api/user/refreshToken',
{
clientType: CLIENT_TYPE,
clientName: CLIENT_NAME,
clientVersion: CLIENT_VERSION
},
{
headers: {
traceId,
timestamp,
sign: sigh,
refreshToken: userData.rt.token
}
}
)
.then(async (refreshRes) => {
if (refreshRes.data.code === 0) {
userData.setAt(refreshRes.data.data.accessToken)
const res = await instance(config)
resolve(res)
while (requestsQueue.length > 0) {
const { resolve, config } = requestsQueue.shift()
const res = await instance(config)
resolve(res)
}
} else {
ElMessage.error(refreshRes.data.desc || '服务异常')
reject(refreshRes.data)
}
})
.catch((refreshErr) => {
ElMessage.error('服务异常')
reject(refreshErr)
})
.finally(() => {
isRefreshing = false
})
}
})
}
export default instance
export { baseURL }