11 changed files with 255 additions and 156 deletions
@ -0,0 +1,23 @@
|
||||
import { defineStore } from 'pinia' |
||||
|
||||
export const useTokenStore = defineStore('token', { |
||||
state: () => ({ |
||||
access_token: null, |
||||
refresh_token: null, |
||||
}), |
||||
actions: { |
||||
setAccessToken(token) { |
||||
this.access_token = token |
||||
}, |
||||
setRefreshToken(token) { |
||||
this.refresh_token = token |
||||
}, |
||||
removeTokens() { |
||||
this.access_token = null |
||||
this.refresh_token = null |
||||
} |
||||
}, |
||||
persist: { |
||||
enabled: true, |
||||
} |
||||
}) |
||||
@ -0,0 +1,76 @@
|
||||
import axios from 'axios' |
||||
import { getActivePinia } from 'pinia' |
||||
import { useTokenStore } from "@/stores/useTokenStore"; |
||||
import router from "@/router"; |
||||
|
||||
axios.defaults.baseURL = '' |
||||
axios.defaults.timeout = 10000 |
||||
|
||||
|
||||
// 注册请求拦截器
|
||||
axios.interceptors.request.use(config => { |
||||
const pinia = getActivePinia() |
||||
const tokens = useTokenStore(pinia) |
||||
|
||||
const accessToken = tokens.access_token |
||||
if (accessToken) { |
||||
config.headers['Authorization'] = 'Bearer ' + accessToken |
||||
// console.log(config.headers)
|
||||
} |
||||
// console.log(config.headers)
|
||||
return config |
||||
}, error => { |
||||
console.log(error) |
||||
return Promise.reject(error) |
||||
}) |
||||
|
||||
// 注册响应拦截器
|
||||
axios.interceptors.response.use(response => { |
||||
const pinia = getActivePinia() |
||||
const tokens = useTokenStore(pinia) |
||||
|
||||
const newAccessToken = response.data.accessToken |
||||
if (newAccessToken) { |
||||
tokens.access_token = newAccessToken |
||||
} |
||||
// console.log("res.interceptors-:" + JSON.stringify(response))
|
||||
return response |
||||
}, async (error) => { |
||||
const pinia = getActivePinia() |
||||
const tokens = useTokenStore(pinia) |
||||
// console.log("err.interceptors-:" + JSON.stringify(error.response))
|
||||
// 401 错误,说明 access_token 过期了,需要用 refresh_token 来刷新
|
||||
if (error.response && error.response.status === 401) { |
||||
const refreshToken = tokens.refresh_token |
||||
if (refreshToken) { |
||||
try { |
||||
// console.log("refresh-token-req:" + refreshToken)
|
||||
const res = await axios.create().post('api/refresh-token', { refreshToken: refreshToken }) |
||||
// console.log("refresh-token-res:" + JSON.stringify(res))
|
||||
// 如果刷新成功,就更新本地存储中的 token,并且重新发送之前失败的请求
|
||||
if (res.data && res.data.accessToken) { |
||||
tokens.setAccessToken(res.data.accessToken) |
||||
tokens.setRefreshToken(res.data.refreshToken) |
||||
return axios.request(error.config) |
||||
} |
||||
} catch (err) { |
||||
// 如果刷新失败,就清除本地存储中的 token,并且跳转到登录页面
|
||||
tokens.removeTokens() |
||||
// 给用户一个提示或者一个重试的机会
|
||||
alert('您的登录已过期,请重新登录') |
||||
// 将用户的当前状态保存起来,以便在登录后恢复
|
||||
localStorage.setItem('current_route', router.currentRoute.value) |
||||
router.push('/login') |
||||
} |
||||
} |
||||
} |
||||
error.message = '请求失败:' + error.message |
||||
if (error.response && error.response.status === 404) { |
||||
error = new NotFoundError(error.message) |
||||
} |
||||
return Promise.reject(error) |
||||
}) |
||||
|
||||
export function request(config) { |
||||
return axios(config) |
||||
} |
||||
Loading…
Reference in new issue