Laravel基于用户类型的路由中间件权限控制方案咨询
路由层面实现三级用户权限控制方案
先明确你的权限规则:
- Guest(未登录访客):仅能访问
/homepage、/login - Admin(管理员):仅能访问
/homepage、/logout、/manage - User(普通用户):仅能访问
/homepage、/logout、/shopping/cart
核心解决思路是用路由守卫/中间件——在请求到达具体页面/接口前,先校验用户角色与当前路由的权限匹配度,不匹配则直接拦截,从根源上禁止无权限访问。
后端路由实现(以Express.js为例)
1. 定义权限映射表
先把角色和允许访问的路由对应起来,方便后续校验:
// 角色-路由权限映射 const roleRouteMap = { guest: ['/homepage', '/login'], admin: ['/homepage', '/logout', '/manage'], user: ['/homepage', '/logout', '/shopping/cart'] };
2. 编写权限校验中间件
这个中间件会在每个路由处理前执行,完成权限判断:
const checkPermission = (req, res, next) => { // 获取当前用户角色:优先从登录态(如session/JWT解析结果)获取,默认为guest const currentRole = req.user?.role || 'guest'; // 获取当前请求的路由路径 const currentPath = req.path; // 校验当前角色是否有权限访问该路由 const allowedPaths = roleRouteMap[currentRole]; if (allowedPaths.includes(currentPath)) { return next(); // 权限通过,继续执行后续逻辑 } // 无权限时的处理:返回403或重定向到首页 res.status(403).send('您没有访问该页面的权限'); // 或者重定向:res.redirect('/homepage'); };
3. 给路由绑定权限中间件
把校验中间件挂载到需要权限控制的路由上:
const express = require('express'); const app = express(); // 给所有需要校验的路由添加中间件 app.get('/homepage', checkPermission, (req, res) => { res.send('首页内容'); }); app.get('/login', checkPermission, (req, res) => { res.send('登录页面'); }); app.get('/logout', checkPermission, (req, res) => { // 注销逻辑:清空session/token res.send('已注销'); }); app.get('/manage', checkPermission, (req, res) => { res.send('管理后台'); }); app.get('/shopping/cart', checkPermission, (req, res) => { res.send('购物车页面'); }); app.listen(3000);
前端路由实现(以Vue Router为例)
如果是前后端分离项目,前端路由也需要做权限拦截(避免用户手动输入地址访问受限页面):
1. 配置路由元信息
在路由规则中通过meta.roles标记允许访问的角色:
const routes = [ { path: '/homepage', component: () => import('@/views/Homepage') }, { path: '/login', component: () => import('@/views/Login') }, { path: '/logout', component: () => import('@/views/Logout') }, { path: '/manage', component: () => import('@/views/Manage'), meta: { roles: ['admin'] } // 仅admin可访问 }, { path: '/shopping/cart', component: () => import('@/views/ShoppingCart'), meta: { roles: ['user'] } // 仅user可访问 } ];
2. 全局前置路由守卫
在路由跳转前校验权限:
const router = createRouter({ history: createWebHistory(), routes }); router.beforeEach((to, from, next) => { // 获取当前用户角色:从登录态(如Vuex/localStorage)获取,默认为guest const currentRole = localStorage.getItem('userRole') || 'guest'; // 特殊处理:已登录用户访问/login,直接重定向到首页 if (to.path === '/login' && currentRole !== 'guest') { return next('/homepage'); } // 白名单路由:guest直接可访问的路由 const whiteList = ['/homepage', '/login']; if (whiteList.includes(to.path)) { return next(); } // 校验当前角色是否在路由允许的角色列表中 if (to.meta.roles && to.meta.roles.includes(currentRole)) { return next(); } // 无权限时重定向到首页 next('/homepage'); });
关键注意事项
- 角色存储要可靠:后端必须从服务器端存储(如session)或签名的JWT中获取角色,不能依赖前端本地存储(易被篡改)。
- 动态路由处理:如果有带参数的路由(如
/manage/:id),需要用正则匹配路径,不要直接用字符串includes判断。 - 默认权限兜底:一定要设置默认角色为
guest,避免未登录用户绕过权限校验。
内容的提问来源于stack exchange,提问作者Dancchi
相关产品推荐
相关产品推荐

