Vue.js路由守卫鉴权:未认证用户访问公共表单页跳转失效
Vue路由公开页面免鉴权实现方案
问题背景
现有项目配置了全局前置路由守卫,每次路由跳转都会请求/user/info接口校验登录状态,未登录用户访问非登录页时会弹出提示并跳转到登录页。现在需要开放路由名为form、路径为/public/form的表单页,允许未认证用户直接访问,手动修改守卫逻辑后未达到预期效果。
原有路由守卫初始代码:
import addToast from '@/utils/toast-queue'; import routes from './routes'; import App from './app'; import './assets/styles/global.scss'; import { jsonRequest } from './utils/requests'; Vue.use(VueRouter); const router = new VueRouter({ routes }); router.beforeEach(async (to, from, next) => { const userInfo = await jsonRequest('GET', '/user/info'); const notAuthenticated = userInfo.status !== 200; if (to.name !== 'login' && notAuthenticated) { if (to.name === 'survey') { next({ name: 'survey' }); } else { addToast('Please login', { type: 'error' }); next({ name: 'login' }); } } else { next(); } }); /* eslint-disable-next-line no-new */ new Vue({ el: '#app', router, render: h => h(App) });
对应公开路由的配置:
{ path: '/public/form', name: 'form', component: () => import('./views/form'), }
失效原因
之前修改的代码存在三个核心问题:
- 白名单判断位置错误:将公开路由的判断放在了
/user/info鉴权请求之后,多数项目的请求封装会在接口返回401/403未授权状态时直接抛出异常、或触发全局登录跳转,会导致后续的白名单判断逻辑根本没有执行机会。 - 跳转逻辑冗余:判断到当前路由是公开的
form页时,调用next({ name: 'form' })会重新触发一次路由跳转,再次进入全局守卫,极端场景会触发路由死循环。 - 无效请求开销:公开路由本身不需要校验登录状态,提前发起鉴权请求属于不必要的资源浪费。
正确实现代码
在路由守卫最开始位置增加公开路由白名单判断,命中白名单的路由直接放行,不进入后续鉴权流程:
// 无需登录即可访问的路由白名单,新增公开页面直接往数组里加路由名即可 const PUBLIC_ROUTES = ['login', 'form', 'survey'] router.beforeEach(async (to, from, next) => { // 命中白名单直接放行,不做任何鉴权逻辑 if (PUBLIC_ROUTES.includes(to.name)) { return next() } const userInfo = await jsonRequest('GET', '/user/info'); const notAuthenticated = userInfo.status !== 200; if (notAuthenticated) { addToast('Please login', { type: 'error' }); next({ name: 'login' }); } else { next(); } });
注意事项
- 调用
next()放行当前路由时,不需要传入当前路由的路径/名称参数,直接调用无参next()即可,避免重复触发路由守卫。 - 白名单维护统一收敛到
PUBLIC_ROUTES数组,后续新增公开页面不需要修改多层嵌套的if判断,维护成本更低。 - 白名单判断必须放在所有异步逻辑之前,确保公开路由不会被鉴权逻辑阻塞。
内容的提问来源于stack exchange,提问作者FrMan
相关产品推荐
相关产品推荐

