This commit is contained in:
chenweiqiang 2025-04-30 10:22:59 +08:00
parent bc8ea41ef7
commit 952f7fc00a
2 changed files with 92 additions and 2 deletions

88
src/utils/auth.js Normal file
View File

@ -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
}
}

View File

@ -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]
} }
// 请求队列(用于取消请求) // 请求队列(用于取消请求)