// 此vm参数为页面的实例,可以通过它引用vuex中的变量
module.exports = (vm) => {
// 初始化请求配置
uni.$u.http.setConfig((config) => {
/* config 为默认全局配置*/
config.baseURL = '/'; /* 根域名 */
config.header = {
}
return config
})
// 请求队列
let requestList = []
// 是否正在刷新中
let isRefreshToken = false
// 请求拦截
uni.$u.http.interceptors.request.use(async (config) => { // 可使用async await 做异步操作
if (['DELETE'].includes(config.method)) {
config.header = {
...config.header,
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
}
config.header["Authorization"] = `Bearer ${uni.getStorageSync("accessToken")}`;
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
})
// 响应拦截
uni.$u.http.interceptors.response.use(async (response) => {
if (response.data.msg === '刷新令牌已过期' || response.data.msg === '无效的刷新令牌') {
return handleAuthorized(response.data)
}
if (response.data.code === 401) {
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
if (!isRefreshToken) {
isRefreshToken = true;
let refreshToken = uni.getStorageSync("refreshToken")
// console.log(refreshToken)
// 1. 如果获取不到刷新令牌,则只能执行登出操作
if (!refreshToken) {
return handleAuthorized(response.data)
}
// 2. 进行刷新访问令牌
try {
const refreshTokenRes = await uni.$u.http.post(
"/member/auth/refresh-token?refreshToken=" +
uni.getStorageSync("refreshToken"))
if (refreshTokenRes.code === 401) {
return handleAuthorized(response.data)
}
// 2.1 刷新成功,则回放队列的请求 + 当前请求
uni.setStorageSync("refreshToken", refreshTokenRes.data.refreshToken)
uni.setStorageSync("accessToken", refreshTokenRes.data.accessToken)
requestList.forEach(cb => cb())
return new Promise(resolve => {
resolve(uni.$u.http.request(response.config))
})
} catch (e) { // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
// 2.2 刷新失败,只回放队列的请求
requestList.forEach(cb => cb())
// 提示是否要登出。即不回放当前请求!不然会形成递归
return handleAuthorized(response.data)
} finally {
requestList = []
isRefreshToken = false
}
} else {
// 添加到队列,等待刷新获取到新的令牌
return new Promise(resolve => {
requestList.push(() => {
resolve(uni.$u.http.request(response.config))
})
})
}
}
uni.hideLoading()
return response.data
}, (response) => {
console.error("网络异常")
return Promise.reject(response)
})
function handleAuthorized(data) {
uni.$u.toast('验证失败,请重新登录');
// 函数节流
uni.$u.throttle(() => {
uni.reLaunch({
url: '/pages/login/login'
});
}, 1000 * 10)
return data
}
}
uniapp使用uview(luch-request),无痛刷新token
于 2022-10-05 17:32:19 首次发布