Laravel 5.1基于角色通过Session限制URL直接访问及视图权限问题
解决Laravel 5.1前后端分离下的角色权限访问控制问题
结合你的场景(前端AngularJS+后端Laravel API,已实现菜单角色区分但存在URL直接访问漏洞),需要前后端双重校验来解决问题,具体方案如下:
一、后端Laravel API:核心权限校验(必须做,前端拦截只是辅助)
后端是权限控制的最后一道防线,必须给每个API接口加上权限校验,防止用户绕过前端直接调用接口。
1. 创建权限验证中间件
首先生成一个自定义中间件来校验用户权限:
php artisan make:middleware CheckPermission
然后在app/Http/Middleware/CheckPermission.php中编写校验逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class CheckPermission { public function handle($request, Closure $next, $permission) { // 获取当前登录用户 $user = Auth::user(); // 若未登录或无对应权限,返回403无权限响应 if (!$user || !in_array($permission, $user->allowedModules)) { // 这里的allowedModules是你查询到的用户可访问菜单模块列表,需提前注入到用户模型或Session中 return response()->json(['message' => '无访问权限'], 403); } return $next($request); } }
2. 注册中间件
在app/Http/Kernel.php的$routeMiddleware数组中添加中间件别名:
'permission' => \App\Http\Middleware\CheckPermission::class,
3. 给API路由绑定权限校验
针对需要权限控制的API路由,添加中间件并指定权限标识(要和你存储的菜单模块标识一致):
// 示例:管理员专属接口 Route::get('/api/admin/statistics', 'AdminController@getStatistics')->middleware('permission:admin_statistics'); // 示例:普通用户&管理员都可访问的接口 Route::get('/api/user/profile', 'UserController@getProfile')->middleware('permission:user_profile');
4. 用户权限的存储建议
你提到已查询到用户可查看的菜单模块,不建议存在Session(跨域场景下Session共享麻烦),更推荐:
- 登录时将权限列表返回给前端,前端存入
localStorage - 后端在用户模型中保留权限获取逻辑(比如从数据库查询),方便中间件实时校验
二、前端AngularJS:路由拦截(提升用户体验)
前端拦截是为了避免用户输URL跳转后才看到后端返回的无权限提示,提前在路由层面拦截。
1. 路由配置添加权限标识
给每个需要权限的路由加上permission属性,和后端的权限标识一一对应:
angular.module('yourApp').config(function($routeProvider) { $routeProvider .when('/admin/dashboard', { templateUrl: 'views/admin/dashboard.html', controller: 'AdminDashboardCtrl', permission: 'admin_statistics' // 和后端权限标识一致 }) .when('/user/profile', { templateUrl: 'views/user/profile.html', controller: 'UserProfileCtrl', permission: 'user_profile' }) .when('/access-denied', { templateUrl: 'views/access-denied.html', controller: 'AccessDeniedCtrl' }) .otherwise({redirectTo: '/'}); });
2. 路由跳转前拦截校验
监听$routeChangeStart事件,在路由跳转前检查用户权限:
angular.module('yourApp').run(function($rootScope, $location) { $rootScope.$on('$routeChangeStart', function(event, nextRoute) { // 若当前路由需要权限校验 if (nextRoute.$$route && nextRoute.$$route.permission) { // 从localStorage取出登录时后端返回的用户权限列表 const userPermissions = JSON.parse(localStorage.getItem('userPermissions')) || []; // 校验权限,无权限则阻止跳转并跳转到无权限页面 if (!userPermissions.includes(nextRoute.$$route.permission)) { event.preventDefault(); $location.path('/access-denied'); } } }); });
三、额外安全补充
- 不要依赖单一校验:前端拦截只是优化体验,真正的安全必须靠后端API的权限校验,因为用户可以通过浏览器调试工具绕过前端直接调用API。
- 跨域场景处理:如果前后端是跨域部署,需要在Laravel中配置CORS中间件,允许携带Cookie/Session或JWT Token:
// 示例CORS中间件核心代码 public function handle($request, Closure $next) { $response = $next($request); $response->header('Access-Control-Allow-Origin', 'http://你的前端域名'); $response->header('Access-Control-Allow-Credentials', 'true'); $response->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); return $response; } - 权限标识统一:前后端的权限标识必须完全一致,避免出现前端判断有权限但后端拒绝的矛盾情况。
内容的提问来源于stack exchange,提问作者user9148653
相关产品推荐
相关产品推荐

