jingrow 2d7be8f7c4 refactor: 移除localStorage存储,改为基于cookie的状态保持
- 移除所有localStorage相关代码,不再保存敏感信息
- 前端UserInfo接口只保留后端实际返回的字段(user, user_type)
- 更新getUserInfoApi和loginApi,只映射后端实际返回的字段
- 更新UserMenu组件,使用user字段替代username
- 状态保持完全基于cookie验证
2026-01-03 01:09:47 +08:00

133 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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