fix: 未登录访问管理后台不再闪现页面,路由守卫改为服务端校验
- 守卫先经 /profile 校验 token 有效后才放行受保护路由,无效 token 直接跳登录并带 redirect 回跳 - DashboardLayout 用户信息就绪前只渲染 spinner,不渲染后台内容 - manager 路由增加 requiresAdmin 校验(role >= 10),非管理员重定向回仪表盘 - 401 拦截器改用 router.push 软跳转,避免整页刷新与双重跳转 - pinia 先于 router 安装;登录页支持 redirect 参数回跳原目标
This commit is contained in:
@@ -1,19 +1,41 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { routes } from '@/utils/router_menu'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const isAuthenticated = localStorage.getItem('token')
|
||||
// 受保护页面必须先通过服务端校验才渲染:
|
||||
// 本地 token 存在不代表有效(可能已过期/被重置),若只查 localStorage,
|
||||
// 页面会先渲染约 1 秒、等 /profile 返回 401 后才被踢回登录页。
|
||||
router.beforeEach(async (to) => {
|
||||
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
|
||||
if (requiresAuth && !isAuthenticated) {
|
||||
next('/login')
|
||||
} else {
|
||||
next()
|
||||
if (!requiresAuth) return true
|
||||
|
||||
const authStore = useAuthStore()
|
||||
|
||||
if (!authStore.token) {
|
||||
return { path: '/login', query: { redirect: to.fullPath } }
|
||||
}
|
||||
|
||||
// 有 token 但还没加载用户信息时,先向服务端确认身份,失败则不得进入
|
||||
if (!authStore.user) {
|
||||
try {
|
||||
await authStore.getProfile()
|
||||
} catch {
|
||||
authStore.clear()
|
||||
return { path: '/login', query: { redirect: to.fullPath } }
|
||||
}
|
||||
}
|
||||
|
||||
// 管理后台仅对 role >= 10 开放
|
||||
if (to.matched.some(record => record.meta.requiresAdmin) && (authStore.user?.role ?? 0) < 10) {
|
||||
return '/dashboard/overview'
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
export default router
|
||||
|
||||
Reference in New Issue
Block a user