Vue-Router异常:无权限校验路径仍跳转至Login页面求助
问题
原本项目运行正常,执行npm update后,访问无需权限校验的/public或/register路径时,仍会被重定向至/login页面。调试发现console.log(to.meta.requiresAuth)返回undefined,console.log(to.name)返回login,且项目中未设置其他重定向或路由重写规则。
路由配置代码
import { createRouter, createWebHistory } from "vue-router"; import Home from "../views/Home.vue"; import PublicPage from "../views/public.vue"; const router = createRouter({ history: createWebHistory(), routes: [{ path: "/public", name: "PublicPage", component: PublicPage, meta: { requiresAuth: false, // No authentication required roles: [], // No specific roles required }, path: "/", name: "Home", component: Home, props: true, meta: { requiresAuth: true, roles: ["Super Admin", "Admin", "Viewer"], }, }, { path: "/test", component: () => import("../views/Test.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin", "Viewer"], }, }, { path: "/map", component: () => import("../views/Map.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin", "Viewer"], }, }, { path: "/contact", component: () => import("../views/Contact.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin", "Viewer"], }, }, { path: "/users", component: () => import("../views/Users.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin"], }, }, { path: "/support", component: () => import("../views/Support.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin", "Viewer"], }, }, { path: "/settings", component: () => import("../views/Settings.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin"], }, }, { path: "/assets", component: () => import("../views/Assets.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin"], }, }, { path: "/alerts", component: () => import("../views/Alerts.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin"], }, }, { path: "/clients", component: () => import("../views/Clients.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin"], //only super admin have access to the company list }, }, { path: "/labels", component: () => import("../views/Labels.vue"), meta: { requiresAuth: true, roles: ["Super Admin", "Admin"], }, }, { path: "/login", name: "Login", component: () => import("../views/authentication/Login.vue"), }, { path: "/register", name: "Register", component: () => import("../views/authentication/Activate.vue"), }, ], }); router.beforeEach((to, from, next) => { const token = localStorage.getItem("token"); if (to.meta.requiresAuth && !token) { next({ name: "Login" }); } else if (token) { const userRole = localStorage.getItem("role"); // implement this function to get the user's role from the backend const authorizedRoles = to.meta.roles; if (authorizedRoles && authorizedRoles.length && authorizedRoles.includes(userRole)) { next(); } else { next({ name: "Home" }); // or redirect to a 403 page } } else { next(); } }); export default router;
原因分析
- 路由语法错误:routes数组的第一个元素中,
/public和/路由被写在同一个对象里。JavaScript对象中重复属性会被后面的覆盖,导致/public路由未被正确注册,访问时找不到对应路由。 - 公开路由meta属性缺失:
/login和/register路由未设置meta.requiresAuth: false,导致to.meta.requiresAuth为undefined,结合vue-router版本更新后的匹配逻辑,触发意外重定向。 - 导航守卫逻辑漏洞:未明确处理
to.meta.requiresAuth为undefined的情况,加上路由匹配异常,最终导致重定向到/login。
解决方案
1. 修复路由语法错误
将第一个路由拆分为两个独立对象,确保/public路由被正确注册:
routes: [ { path: "/public", name: "PublicPage", component: PublicPage, meta: { requiresAuth: false, roles: [], }, }, { path: "/", name: "Home", component: Home, props: true, meta: { requiresAuth: true, roles: ["Super Admin", "Admin", "Viewer"], }, }, // 其余路由保持不变 ]
2. 给公开路由明确设置meta属性
为/login和/register路由添加meta.requiresAuth: false,避免undefined的情况:
{ path: "/login", name: "Login", component: () => import("../views/authentication/Login.vue"), meta: { requiresAuth: false }, }, { path: "/register", name: "Register", component: () => import("../views/authentication/Activate.vue"), meta: { requiresAuth: false }, },
3. 优化导航守卫逻辑
在导航守卫中明确处理to.meta.requiresAuth为undefined的情况,默认视为无需认证:
router.beforeEach((to, from, next) => { const token = localStorage.getItem("token"); // 明确处理requiresAuth的默认值,undefined视为false const requiresAuth = to.meta.requiresAuth ?? false; if (requiresAuth && !token) { next({ name: "Login" }); } else if (token) { const userRole = localStorage.getItem("role"); const authorizedRoles = to.meta.roles; // 对于不需要角色校验的路由直接放行 if (!authorizedRoles || authorizedRoles.length === 0) { next(); } else if (authorizedRoles.includes(userRole)) { next(); } else { next({ name: "Home" }); // 或重定向到403页面 } } else { next(); } });
验证
修改后重新启动项目,访问/public、/login、/register路径应能正常访问;访问需要权限的路由时,未登录状态下会正确重定向到/login,登录后根据角色匹配正确路由。
内容的提问来源于stack exchange,提问作者Azay Karimli
相关产品推荐
相关产品推荐

