- 移除所有localStorage相关代码,不再保存敏感信息 - 前端UserInfo接口只保留后端实际返回的字段(user, user_type) - 更新getUserInfoApi和loginApi,只映射后端实际返回的字段 - 更新UserMenu组件,使用user字段替代username - 状态保持完全基于cookie验证
133 lines
3.2 KiB
TypeScript
133 lines
3.2 KiB
TypeScript
import { defineStore } from 'pinia'
|
||
import { ref, computed } from 'vue'
|
||
import { loginApi, getUserInfoApi, logoutApi, isCookieExpired, getSessionUser } from '../api/auth'
|
||
import { setInitializingAuth } from '../utils/fetchInterceptor'
|
||
|
||
export interface User {
|
||
user: string
|
||
user_type: string
|
||
}
|
||
|
||
export const useAuthStore = defineStore('auth', () => {
|
||
const user = ref<User | null>(null)
|
||
const loading = ref(false)
|
||
const isAuthenticated = ref(false)
|
||
|
||
const isLoggedIn = computed(() => isAuthenticated.value && !!user.value)
|
||
|
||
// 判断是否是认证错误
|
||
const isAuthError = (error: any): boolean => {
|
||
return error?.status === 401 ||
|
||
error?.status === 403 ||
|
||
error?.message?.includes('过期') ||
|
||
error?.message?.includes('Cookie已过期')
|
||
}
|
||
|
||
// 设置用户状态(统一的状态更新方法,不保存到localStorage)
|
||
const setUserState = (userInfo: User) => {
|
||
user.value = userInfo
|
||
isAuthenticated.value = true
|
||
}
|
||
|
||
// 清除用户状态
|
||
const clearUserState = () => {
|
||
user.value = null
|
||
isAuthenticated.value = false
|
||
}
|
||
|
||
// 验证并更新用户信息
|
||
const validateAndUpdateUser = async (): Promise<boolean> => {
|
||
try {
|
||
const userInfo = await getUserInfoApi()
|
||
setUserState(userInfo)
|
||
return true
|
||
} catch (error: any) {
|
||
console.error('验证用户信息失败:', error)
|
||
if (isAuthError(error)) {
|
||
clearUserState()
|
||
}
|
||
return false
|
||
}
|
||
}
|
||
|
||
const login = async (username: string, password: string) => {
|
||
loading.value = true
|
||
try {
|
||
const response = await loginApi(username, password)
|
||
|
||
if (response.user) {
|
||
setUserState(response.user)
|
||
return { success: true, user: response.user }
|
||
} else {
|
||
return { success: false, error: response.message || '登录失败' }
|
||
}
|
||
} catch (error: any) {
|
||
console.error('登录错误:', error)
|
||
return { success: false, error: error.message || '登录失败' }
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
const logout = async () => {
|
||
try {
|
||
await logoutApi()
|
||
} catch (error) {
|
||
console.error('登出错误:', error)
|
||
} finally {
|
||
clearUserState()
|
||
}
|
||
}
|
||
|
||
const initAuth = async () => {
|
||
setInitializingAuth(true)
|
||
|
||
try {
|
||
// 检查cookie状态
|
||
const userId = getSessionUser()
|
||
const hasSessionCookie = !isCookieExpired()
|
||
const hasCookie = userId || hasSessionCookie
|
||
|
||
// 如果没有cookie,清除认证状态
|
||
if (!hasCookie) {
|
||
if (isAuthenticated.value) {
|
||
clearUserState()
|
||
}
|
||
return
|
||
}
|
||
|
||
// 如果有cookie,尝试验证并获取用户信息
|
||
if (hasCookie) {
|
||
await validateAndUpdateUser()
|
||
}
|
||
} finally {
|
||
setInitializingAuth(false)
|
||
}
|
||
}
|
||
|
||
const updateUserInfo = async () => {
|
||
if (!isAuthenticated.value) return
|
||
|
||
try {
|
||
const userInfo = await getUserInfoApi()
|
||
setUserState(userInfo)
|
||
} catch (error: any) {
|
||
console.error('更新用户信息失败:', error)
|
||
if (isAuthError(error)) {
|
||
await logout()
|
||
}
|
||
}
|
||
}
|
||
|
||
return {
|
||
user,
|
||
loading,
|
||
isAuthenticated,
|
||
isLoggedIn,
|
||
login,
|
||
logout,
|
||
initAuth,
|
||
updateUserInfo
|
||
}
|
||
})
|