前端路由鉴权怎么做才能防止用户直接访问页面?

IT人自雨 阅读 3

我在用 Vue Router 做后台管理系统,想限制未登录用户不能进 /admin 页面。现在是通过 router.beforeEach 判断 token,但刷新页面后还是会闪一下内容,而且直接输入 URL 还是能进去,这咋办?

我试过在 beforeEach 里加 next('/login'),但好像时机不对,页面组件还是先渲染了。有没有更稳妥的方案?比如在路由配置里直接加个 meta 字段控制?

const routes = [
  {
    path: '/admin',
    component: Admin,
    meta: { requiresAuth: true }
  }
]

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !localStorage.getItem('token')) {
    next('/login')
  } else {
    next()
  }
})
我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
嘉俊 Dev
你这个问题我也踩过坑,确实 beforeEach 拦截的时机比较微妙。推荐的做法是结合路由守卫和路由懒加载,我来说下具体怎么搞。

首先你的 meta 字段思路是对的,这是 Vue Router 官方文档推荐的方式。但关键是要在路由配置时就用 import() 动态导入组件,而不是静态引入。这样守卫拦截时组件根本不会加载:

const routes = [
{
path: '/admin',
component: () => import('./Admin.vue'),
meta: { requiresAuth: true }
}
]


然后守卫这里要调整下,建议加个 loading 状态避免闪屏:

router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!localStorage.getItem('token')) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next()
}
})


注意这里用了 to.matched.some 来检查嵌套路由的 meta 字段,比直接判断 to.meta 更稳妥。另外加了 redirect 参数方便登录后跳回原来页面。

至于刷新闪屏的问题,建议在 App.vue 里加个全局 loading,等路由守卫检查完再显示内容。这个套路我在好几个后台系统都用过,稳得一批。

最后提一嘴,token 最好用 vuex 持久化配合 localStorage,单纯用 localStorage 在 SSR 环境下会有问题。不过你这个场景应该够用了。
点赞
2026-03-10 12:12