重构登陆登出,对齐dashboard的认证方式

This commit is contained in:
jingrow 2025-12-27 22:01:21 +08:00
parent fd70b4149d
commit f59809023a
4 changed files with 75 additions and 110 deletions

View File

@ -215,10 +215,8 @@ router.beforeEach(async (to, _from, next) => {
const authStore = useAuthStore()
// 如果正在前往登录页,不需要初始化认证(避免重新设置状态)
if (!authStore.isAuthenticated && to.path !== '/login' && to.path !== '/signup') {
await authStore.initAuth()
}
// 初始化认证状态(从 cookie 读取)
await authStore.initAuth()
if (to.path.startsWith('/tools/') && to.name !== 'Tools') {
// 如果路由已经匹配,直接通过

View File

@ -1,8 +1,3 @@
export interface LoginResponse {
message: string
user: UserInfo
}
export interface UserInfo {
id: string
username: string
@ -33,7 +28,7 @@ export function isCookieExpired(): boolean {
return !sessionCookie
}
export const loginApi = async (username: string, password: string): Promise<LoginResponse> => {
export const loginApi = async (username: string, password: string): Promise<void> => {
const response = await fetch(`/api/action/login`, {
method: 'POST',
headers: {
@ -52,35 +47,8 @@ export const loginApi = async (username: string, password: string): Promise<Logi
throw new Error(errorData.detail || errorData.message || errorData.exc || '登录请求失败')
}
const data = await response.json()
// dashboard 登录接口成功后会设置 cookie返回的数据可能不包含 user 对象
// 需要通过 cookie 获取用户信息
// 登录成功,尝试获取用户信息
try {
const userInfo = await getUserInfoApi()
return { message: data.message || 'Logged In', user: userInfo }
} catch (error: any) {
// 如果获取用户信息失败,但登录成功,尝试从 cookie 获取基本信息
const sessionUser = getSessionUser()
if (sessionUser) {
// 返回基本用户信息
return {
message: data.message || 'Logged In',
user: {
id: sessionUser,
username: sessionUser,
email: username.includes('@') ? username : '',
avatar: '',
first_name: '',
last_name: '',
user_type: ''
}
}
}
// 如果都失败了,抛出错误
throw new Error(error.message || '登录成功但获取用户信息失败')
}
// dashboard 登录接口成功后会设置 cookie不需要返回数据
// 登录状态通过 cookie 判断
}
// 获取用户信息

View File

@ -16,26 +16,46 @@ export interface User {
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)
// 直接从 cookie 获取用户,与 dashboard 对齐
const getSessionUser = () => {
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
const sessionUser = cookies.get('user_id')
if (!sessionUser || sessionUser === 'Guest') {
return null
}
return sessionUser
}
// 登录状态完全依赖 cookie与 dashboard 对齐
const isLoggedIn = computed(() => {
const sessionUser = getSessionUser()
return !!sessionUser
})
const login = async (username: string, password: string) => {
loading.value = true
try {
const response = await loginApi(username, password)
await loginApi(username, password)
if (response.user) {
user.value = response.user
isAuthenticated.value = true
// 登录成功后,从 cookie 获取用户信息
const sessionUser = getSessionUser()
if (sessionUser) {
user.value = {
id: sessionUser,
username: sessionUser,
email: username.includes('@') ? username : '',
avatar: '',
first_name: '',
last_name: '',
user_type: ''
}
// 保存登录状态到localStorage
localStorage.setItem('jingrow_user', JSON.stringify(response.user))
localStorage.setItem('jingrow_authenticated', 'true')
return { success: true, user: response.user }
// 登录成功后直接跳转,与 dashboard 对齐
window.location.href = '/'
return { success: true }
} else {
return { success: false, error: response.message || '登录失败' }
return { success: false, error: '登录失败' }
}
} catch (error: any) {
console.error('登录错误:', error)
@ -51,79 +71,59 @@ export const useAuthStore = defineStore('auth', () => {
} catch (error) {
console.error('登出错误:', error)
} finally {
// 清除本地状态(先清除状态,再跳转)
// 清除本地状态
user.value = null
isAuthenticated.value = false
localStorage.removeItem('jingrow_user')
localStorage.removeItem('jingrow_authenticated')
// 使用 window.location 强制跳转,避免路由守卫干扰
window.location.href = '/login'
// 登出后重新加载页面,与 dashboard 对齐
window.location.reload()
}
}
const initAuth = async () => {
// 检查user_id是否为Guestcookie过期时后端会设置为Guest
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
const userId = cookies.get('user_id')
if (userId === 'Guest') {
// user_id是Guest说明cookie已过期清除本地状态
if (isAuthenticated.value) {
await logout()
}
return
}
// 首先检查session cookie是否存在
if (!isCookieExpired()) {
try {
const userInfo = await getUserInfoApi()
user.value = userInfo
isAuthenticated.value = true
// 更新localStorage
localStorage.setItem('jingrow_user', JSON.stringify(userInfo))
localStorage.setItem('jingrow_authenticated', 'true')
return
} catch (error: any) {
console.error('验证用户信息失败:', error)
if (error.status === 401 || error.status === 403 || error.message?.includes('过期')) {
await logout()
// 直接从 cookie 获取用户,与 dashboard 对齐
const sessionUser = getSessionUser()
if (sessionUser) {
// 从 localStorage 恢复用户信息(如果有)
const savedUser = localStorage.getItem('jingrow_user')
if (savedUser) {
try {
user.value = JSON.parse(savedUser)
} catch {
// 如果解析失败,使用基本信息
user.value = {
id: sessionUser,
username: sessionUser,
email: '',
avatar: '',
first_name: '',
last_name: '',
user_type: ''
}
}
return
}
}
// session cookie不存在检查localStorage
const savedUser = localStorage.getItem('jingrow_user')
const savedAuth = localStorage.getItem('jingrow_authenticated')
if (savedUser && savedAuth === 'true') {
try {
user.value = JSON.parse(savedUser)
isAuthenticated.value = true
// 验证用户信息是否仍然有效
const userInfo = await getUserInfoApi()
user.value = userInfo
localStorage.setItem('jingrow_user', JSON.stringify(userInfo))
} catch (error: any) {
console.error('验证用户信息失败:', error)
if (error.status === 401 || error.status === 403 || error.message?.includes('过期')) {
await logout()
} else {
logout()
} else {
// 没有缓存,使用基本信息
user.value = {
id: sessionUser,
username: sessionUser,
email: '',
avatar: '',
first_name: '',
last_name: '',
user_type: ''
}
}
} else {
if (isAuthenticated.value) {
await logout()
}
// 未登录,清除状态
user.value = null
localStorage.removeItem('jingrow_user')
localStorage.removeItem('jingrow_authenticated')
}
}
const updateUserInfo = async () => {
if (!isAuthenticated.value) return
if (!isLoggedIn.value) return
try {
const userInfo = await getUserInfoApi()
@ -141,7 +141,6 @@ export const useAuthStore = defineStore('auth', () => {
return {
user,
loading,
isAuthenticated,
isLoggedIn,
login,
logout,

View File

@ -229,7 +229,7 @@ const handleSignup = async () => {
message.success(t('Sign up successful'))
if (result.user) {
authStore.user = result.user
authStore.isAuthenticated = true
// cookie
localStorage.setItem('jingrow_user', JSON.stringify(result.user))
localStorage.setItem('jingrow_authenticated', 'true')
router.push('/')