优化页面、修复BUG
This commit is contained in:
111
client/src/composables/useAuth.ts
Normal file
111
client/src/composables/useAuth.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { ref } from 'vue'
|
||||
import router from '../router'
|
||||
|
||||
const TOKEN_KEY = 'token'
|
||||
const USER_KEY = 'user'
|
||||
const EXPIRE_KEY = 'tokenExpireAt'
|
||||
|
||||
const sessionExpired = ref(false)
|
||||
let sessionExpiredHandled = false
|
||||
let expiryTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
export function useAuth() {
|
||||
const getToken = () => localStorage.getItem(TOKEN_KEY)
|
||||
|
||||
const getTokenExpireAt = (): number => {
|
||||
const raw = localStorage.getItem(EXPIRE_KEY)
|
||||
return raw ? Number(raw) : 0
|
||||
}
|
||||
|
||||
const isAuthenticated = (): boolean => {
|
||||
const token = getToken()
|
||||
if (!token) return false
|
||||
|
||||
const expireAt = getTokenExpireAt()
|
||||
if (expireAt > 0 && Date.now() >= expireAt) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const login = (token: string, user: unknown, expireUnixSeconds: number) => {
|
||||
localStorage.setItem(TOKEN_KEY, token)
|
||||
localStorage.setItem(USER_KEY, JSON.stringify(user))
|
||||
localStorage.setItem(EXPIRE_KEY, String(expireUnixSeconds * 1000))
|
||||
sessionExpiredHandled = false
|
||||
sessionExpired.value = false
|
||||
scheduleExpiryCheck()
|
||||
}
|
||||
|
||||
const logout = (showToast?: (msg: string, type: 'success' | 'error') => void) => {
|
||||
clearExpiryTimer()
|
||||
localStorage.removeItem(TOKEN_KEY)
|
||||
localStorage.removeItem(USER_KEY)
|
||||
localStorage.removeItem(EXPIRE_KEY)
|
||||
sessionExpiredHandled = false
|
||||
sessionExpired.value = false
|
||||
|
||||
if (router.currentRoute.value.path !== '/login') {
|
||||
router.push('/login')
|
||||
}
|
||||
|
||||
if (showToast) {
|
||||
// noop by default for expiry flow
|
||||
}
|
||||
}
|
||||
|
||||
const clearExpiryTimer = () => {
|
||||
if (expiryTimer) {
|
||||
clearTimeout(expiryTimer)
|
||||
expiryTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
const scheduleExpiryCheck = () => {
|
||||
clearExpiryTimer()
|
||||
const expireAt = getTokenExpireAt()
|
||||
if (!expireAt) return
|
||||
|
||||
const delay = expireAt - Date.now()
|
||||
if (delay <= 0) {
|
||||
handleSessionExpired()
|
||||
return
|
||||
}
|
||||
|
||||
expiryTimer = setTimeout(() => {
|
||||
handleSessionExpired()
|
||||
}, delay)
|
||||
}
|
||||
|
||||
const handleSessionExpired = () => {
|
||||
if (sessionExpiredHandled) return
|
||||
sessionExpiredHandled = true
|
||||
sessionExpired.value = true
|
||||
}
|
||||
|
||||
const confirmSessionExpired = () => {
|
||||
logout()
|
||||
}
|
||||
|
||||
const getUser = () => {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem(USER_KEY) || '{}')
|
||||
} catch {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
sessionExpired,
|
||||
getToken,
|
||||
getTokenExpireAt,
|
||||
isAuthenticated,
|
||||
login,
|
||||
logout,
|
||||
handleSessionExpired,
|
||||
confirmSessionExpired,
|
||||
scheduleExpiryCheck,
|
||||
getUser,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user