重构登陆登出,对齐dashboard的认证方式
This commit is contained in:
parent
fd70b4149d
commit
f59809023a
@ -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') {
|
||||
// 如果路由已经匹配,直接通过
|
||||
|
||||
@ -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 判断
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
|
||||
@ -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是否为Guest(cookie过期时后端会设置为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,
|
||||
|
||||
@ -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('/')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user