重构登陆登出,对齐dashboard的认证方式
This commit is contained in:
parent
fd70b4149d
commit
f59809023a
@ -215,10 +215,8 @@ router.beforeEach(async (to, _from, next) => {
|
|||||||
|
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
// 如果正在前往登录页,不需要初始化认证(避免重新设置状态)
|
// 初始化认证状态(从 cookie 读取)
|
||||||
if (!authStore.isAuthenticated && to.path !== '/login' && to.path !== '/signup') {
|
await authStore.initAuth()
|
||||||
await authStore.initAuth()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to.path.startsWith('/tools/') && to.name !== 'Tools') {
|
if (to.path.startsWith('/tools/') && to.name !== 'Tools') {
|
||||||
// 如果路由已经匹配,直接通过
|
// 如果路由已经匹配,直接通过
|
||||||
|
|||||||
@ -1,8 +1,3 @@
|
|||||||
export interface LoginResponse {
|
|
||||||
message: string
|
|
||||||
user: UserInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UserInfo {
|
export interface UserInfo {
|
||||||
id: string
|
id: string
|
||||||
username: string
|
username: string
|
||||||
@ -33,7 +28,7 @@ export function isCookieExpired(): boolean {
|
|||||||
return !sessionCookie
|
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`, {
|
const response = await fetch(`/api/action/login`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -52,35 +47,8 @@ export const loginApi = async (username: string, password: string): Promise<Logi
|
|||||||
throw new Error(errorData.detail || errorData.message || errorData.exc || '登录请求失败')
|
throw new Error(errorData.detail || errorData.message || errorData.exc || '登录请求失败')
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json()
|
// dashboard 登录接口成功后会设置 cookie,不需要返回数据
|
||||||
|
// 登录状态通过 cookie 判断
|
||||||
// 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 || '登录成功但获取用户信息失败')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
|
|||||||
@ -16,26 +16,46 @@ export interface User {
|
|||||||
export const useAuthStore = defineStore('auth', () => {
|
export const useAuthStore = defineStore('auth', () => {
|
||||||
const user = ref<User | null>(null)
|
const user = ref<User | null>(null)
|
||||||
const loading = ref(false)
|
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) => {
|
const login = async (username: string, password: string) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const response = await loginApi(username, password)
|
await loginApi(username, password)
|
||||||
|
|
||||||
if (response.user) {
|
// 登录成功后,从 cookie 获取用户信息
|
||||||
user.value = response.user
|
const sessionUser = getSessionUser()
|
||||||
isAuthenticated.value = true
|
if (sessionUser) {
|
||||||
|
user.value = {
|
||||||
|
id: sessionUser,
|
||||||
|
username: sessionUser,
|
||||||
|
email: username.includes('@') ? username : '',
|
||||||
|
avatar: '',
|
||||||
|
first_name: '',
|
||||||
|
last_name: '',
|
||||||
|
user_type: ''
|
||||||
|
}
|
||||||
|
|
||||||
// 保存登录状态到localStorage
|
// 登录成功后直接跳转,与 dashboard 对齐
|
||||||
localStorage.setItem('jingrow_user', JSON.stringify(response.user))
|
window.location.href = '/'
|
||||||
localStorage.setItem('jingrow_authenticated', 'true')
|
return { success: true }
|
||||||
|
|
||||||
return { success: true, user: response.user }
|
|
||||||
} else {
|
} else {
|
||||||
return { success: false, error: response.message || '登录失败' }
|
return { success: false, error: '登录失败' }
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('登录错误:', error)
|
console.error('登录错误:', error)
|
||||||
@ -51,79 +71,59 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('登出错误:', error)
|
console.error('登出错误:', error)
|
||||||
} finally {
|
} finally {
|
||||||
// 清除本地状态(先清除状态,再跳转)
|
// 清除本地状态
|
||||||
user.value = null
|
user.value = null
|
||||||
isAuthenticated.value = false
|
|
||||||
localStorage.removeItem('jingrow_user')
|
localStorage.removeItem('jingrow_user')
|
||||||
localStorage.removeItem('jingrow_authenticated')
|
localStorage.removeItem('jingrow_authenticated')
|
||||||
|
|
||||||
// 使用 window.location 强制跳转,避免路由守卫干扰
|
// 登出后重新加载页面,与 dashboard 对齐
|
||||||
window.location.href = '/login'
|
window.location.reload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const initAuth = async () => {
|
const initAuth = async () => {
|
||||||
// 检查user_id是否为Guest(cookie过期时后端会设置为Guest)
|
// 直接从 cookie 获取用户,与 dashboard 对齐
|
||||||
const cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
|
const sessionUser = getSessionUser()
|
||||||
const userId = cookies.get('user_id')
|
if (sessionUser) {
|
||||||
if (userId === 'Guest') {
|
// 从 localStorage 恢复用户信息(如果有)
|
||||||
// user_id是Guest,说明cookie已过期,清除本地状态
|
const savedUser = localStorage.getItem('jingrow_user')
|
||||||
if (isAuthenticated.value) {
|
if (savedUser) {
|
||||||
await logout()
|
try {
|
||||||
}
|
user.value = JSON.parse(savedUser)
|
||||||
return
|
} catch {
|
||||||
}
|
// 如果解析失败,使用基本信息
|
||||||
|
user.value = {
|
||||||
// 首先检查session cookie是否存在
|
id: sessionUser,
|
||||||
if (!isCookieExpired()) {
|
username: sessionUser,
|
||||||
try {
|
email: '',
|
||||||
const userInfo = await getUserInfoApi()
|
avatar: '',
|
||||||
user.value = userInfo
|
first_name: '',
|
||||||
isAuthenticated.value = true
|
last_name: '',
|
||||||
|
user_type: ''
|
||||||
// 更新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()
|
|
||||||
}
|
}
|
||||||
return
|
} else {
|
||||||
}
|
// 没有缓存,使用基本信息
|
||||||
}
|
user.value = {
|
||||||
|
id: sessionUser,
|
||||||
// session cookie不存在,检查localStorage
|
username: sessionUser,
|
||||||
const savedUser = localStorage.getItem('jingrow_user')
|
email: '',
|
||||||
const savedAuth = localStorage.getItem('jingrow_authenticated')
|
avatar: '',
|
||||||
|
first_name: '',
|
||||||
if (savedUser && savedAuth === 'true') {
|
last_name: '',
|
||||||
try {
|
user_type: ''
|
||||||
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 {
|
} else {
|
||||||
if (isAuthenticated.value) {
|
// 未登录,清除状态
|
||||||
await logout()
|
user.value = null
|
||||||
}
|
localStorage.removeItem('jingrow_user')
|
||||||
|
localStorage.removeItem('jingrow_authenticated')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateUserInfo = async () => {
|
const updateUserInfo = async () => {
|
||||||
if (!isAuthenticated.value) return
|
if (!isLoggedIn.value) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const userInfo = await getUserInfoApi()
|
const userInfo = await getUserInfoApi()
|
||||||
@ -141,7 +141,6 @@ export const useAuthStore = defineStore('auth', () => {
|
|||||||
return {
|
return {
|
||||||
user,
|
user,
|
||||||
loading,
|
loading,
|
||||||
isAuthenticated,
|
|
||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
login,
|
login,
|
||||||
logout,
|
logout,
|
||||||
|
|||||||
@ -229,7 +229,7 @@ const handleSignup = async () => {
|
|||||||
message.success(t('Sign up successful'))
|
message.success(t('Sign up successful'))
|
||||||
if (result.user) {
|
if (result.user) {
|
||||||
authStore.user = result.user
|
authStore.user = result.user
|
||||||
authStore.isAuthenticated = true
|
// 登录状态由 cookie 决定,不需要手动设置
|
||||||
localStorage.setItem('jingrow_user', JSON.stringify(result.user))
|
localStorage.setItem('jingrow_user', JSON.stringify(result.user))
|
||||||
localStorage.setItem('jingrow_authenticated', 'true')
|
localStorage.setItem('jingrow_authenticated', 'true')
|
||||||
router.push('/')
|
router.push('/')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user