modify
This commit is contained in:
parent
bc8ea41ef7
commit
952f7fc00a
|
|
@ -0,0 +1,88 @@
|
||||||
|
let isRefreshing = false // 刷新状态锁
|
||||||
|
let requestsQueue = [] // 等待队列
|
||||||
|
|
||||||
|
// 核心拦截器
|
||||||
|
export const authInterceptor = async (config) => {
|
||||||
|
// 1. 获取当前 Token
|
||||||
|
let token = uni.getStorageSync('token')
|
||||||
|
const refreshToken = uni.getStorageSync('refreshToken')
|
||||||
|
|
||||||
|
// 2. 检查是否需要跳过认证
|
||||||
|
if (config.skipAuth) return config
|
||||||
|
|
||||||
|
// 3. 自动添加 Authorization 头
|
||||||
|
if (token) {
|
||||||
|
config.header = {
|
||||||
|
...config.header,
|
||||||
|
Authorization: `Bearer ${token}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 小程序 HTTPS 强制转换
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
if (config.url.startsWith('http:')) {
|
||||||
|
config.url = config.url.replace('http:', 'https:')
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新 Token 逻辑
|
||||||
|
const refreshTokenRequest = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await uni.request({
|
||||||
|
url: '/auth/refresh',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
refresh_token: uni.getStorageSync('refreshToken')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 更新存储
|
||||||
|
uni.setStorageSync('token', data.token)
|
||||||
|
uni.setStorageSync('refreshToken', data.refreshToken)
|
||||||
|
return data.token
|
||||||
|
} catch (error) {
|
||||||
|
// 刷新失败跳转登录
|
||||||
|
uni.removeStorageSync('token')
|
||||||
|
uni.removeStorageSync('refreshToken')
|
||||||
|
uni.reLaunch({ url: '/pages/login/login' })
|
||||||
|
throw new Error('登录已过期,请重新登录')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 响应拦截器处理 Token 过期
|
||||||
|
export const authErrorHandler = async (error) => {
|
||||||
|
const { statusCode, config } = error
|
||||||
|
|
||||||
|
// 1. 非 401 错误直接抛出
|
||||||
|
if (statusCode !== 401 || config.skipAuth) throw error
|
||||||
|
|
||||||
|
// 2. 正在刷新时缓存请求
|
||||||
|
if (isRefreshing) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
requestsQueue.push(() => resolve(http.request(config)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 标记刷新状态
|
||||||
|
isRefreshing = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 4. 执行 Token 刷新
|
||||||
|
const newToken = await refreshTokenRequest()
|
||||||
|
|
||||||
|
// 5. 更新原请求头
|
||||||
|
config.header.Authorization = `Bearer ${newToken}`
|
||||||
|
|
||||||
|
// 6. 重试所有等待请求
|
||||||
|
requestsQueue.forEach(cb => cb())
|
||||||
|
requestsQueue = []
|
||||||
|
|
||||||
|
// 7. 重试当前请求
|
||||||
|
return http.request(config)
|
||||||
|
} finally {
|
||||||
|
isRefreshing = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { authInterceptor, authErrorHandler } from './auth'
|
||||||
|
|
||||||
class Request {
|
class Request {
|
||||||
constructor() {
|
constructor() {
|
||||||
// 全局默认配置
|
// 全局默认配置
|
||||||
|
|
@ -16,8 +18,8 @@ class Request {
|
||||||
|
|
||||||
// 拦截器存储
|
// 拦截器存储
|
||||||
this.interceptors = {
|
this.interceptors = {
|
||||||
request: [],
|
request: [authInterceptor],
|
||||||
response: []
|
response: [authErrorHandler]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 请求队列(用于取消请求)
|
// 请求队列(用于取消请求)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue