You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');
            }
        }
    });
});

三、额外安全补充

  1. 不要依赖单一校验:前端拦截只是优化体验,真正的安全必须靠后端API的权限校验,因为用户可以通过浏览器调试工具绕过前端直接调用API。
  2. 跨域场景处理:如果前后端是跨域部署,需要在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;
    }
    
  3. 权限标识统一:前后端的权限标识必须完全一致,避免出现前端判断有权限但后端拒绝的矛盾情况。

内容的提问来源于stack exchange,提问作者user9148653

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:06:55