This commit is contained in:
kazusa 2025-08-29 11:01:21 +08:00
parent c7317e3b8c
commit ffe81c64f5
3 changed files with 55 additions and 17 deletions

View File

@ -84,13 +84,19 @@ const router = createRouter({
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
const userStore = useUserStore() const userStore = useUserStore()
if (to.meta.requiresAuth && !userStore.token) { // 如果要访问需要认证的页面但没有token
if (to.meta.requiresAuth && !userStore.getToken()) {
next('/login') next('/login')
} else if (to.path === '/login' && userStore.token) { return
next('/')
} else {
next()
} }
// 如果已经登录,访问登录页,重定向到首页
if (to.path === '/login' && userStore.getToken()) {
next('/')
return
}
next()
}) })
// 路由后置守卫 - 添加标签页 // 路由后置守卫 - 添加标签页

View File

@ -176,9 +176,13 @@ export const useUserStore = defineStore('user', () => {
// 登出 // 登出
const logout = async () => { const logout = async () => {
try { try {
await authApi.logout() // 只有在有token的情况下才调用logout接口
if (token.value) {
await authApi.logout()
}
} catch (error) { } catch (error) {
console.error('登出失败:', error) console.error('登出接口调用失败:', error)
// 即使接口调用失败,也要清除本地数据
} finally { } finally {
// 清除所有存储的数据 // 清除所有存储的数据
removeToken() removeToken()
@ -221,12 +225,21 @@ export const useUserStore = defineStore('user', () => {
if (token.value && !userInfo.value) { if (token.value && !userInfo.value) {
// 先尝试从缓存加载 // 先尝试从缓存加载
if (!loadCachedUserInfo()) { if (!loadCachedUserInfo()) {
// 缓存无效,从服务器获取 // 缓存无效,延迟从服务器获取,避免在应用初始化时立即发送请求
getUserInfo().catch(() => { setTimeout(() => {
// 如果获取用户信息失败清除无效token if (token.value && !userInfo.value) {
removeToken() getUserInfo().catch((error) => {
clearUserCache() console.error('获取用户信息失败:', error)
}) // 如果获取用户信息失败清除无效token
removeToken()
clearUserCache()
// 如果当前不在登录页,跳转到登录页
if (router.currentRoute.value.path !== '/login') {
router.push('/login')
}
})
}
}, 100)
} }
} }

View File

@ -29,6 +29,9 @@ request.interceptors.request.use(
} }
) )
// 防止循环调用logout的标记
let isLoggingOut = false
// 响应拦截器 // 响应拦截器
request.interceptors.response.use( request.interceptors.response.use(
(response: AxiosResponse) => { (response: AxiosResponse) => {
@ -44,16 +47,32 @@ request.interceptors.response.use(
return Promise.reject(res) return Promise.reject(res)
}, },
(error) => { (error) => {
const { response } = error const { response, config } = error
if (response) { if (response) {
const { status, data } = response const { status, data } = response
switch (status) { switch (status) {
case 401: case 401:
ElMessage.error('认证失败,请重新登录') // 如果是logout请求本身失败或者已经在登出过程中直接跳转登录页
useUserStore().logout() if (config?.url?.includes('/auth/logout') || isLoggingOut) {
router.push('/login') console.log('logout请求失败或正在登出中直接跳转登录页')
isLoggingOut = false
const userStore = useUserStore()
userStore.removeToken()
userStore.clearUserCache()
router.push('/login')
return Promise.reject(error)
}
// 防止重复登出
if (!isLoggingOut) {
isLoggingOut = true
ElMessage.error('认证失败,请重新登录')
useUserStore().logout().finally(() => {
isLoggingOut = false
})
}
break break
case 403: case 403:
ElMessage.error('权限不足') ElMessage.error('权限不足')