必须通过服务端中间件拦截菜单访问,仅前端隐藏无效;创建MenuPermissionCheck中间件校验Admin::user()->can('users.index'),注册为'menu.auth',绑定到对应路由,并确保菜单permission字段与权限slug一致。

在 Laravel-admin 中,菜单访问权限不能只靠前端隐藏来实现,必须配合服务端中间件做真实拦截。否则用户手动输入 URL 仍可绕过菜单栏直接访问受限页面。
注册并绑定权限中间件到菜单路由
Laravel-admin 的菜单项最终都映射到具体路由(如 admin/users),而这些路由默认由框架自动注册。要控制菜单访问,关键不是改菜单配置,而是为对应路由加中间件。
- 先创建中间件:运行
php artisan make:middleware MenuPermissionCheck - 在
handle()方法中校验当前用户是否拥有该菜单所需的权限标识(slug),例如:Admin::user()->can('users.index') - 在
app/Http/Kernel.php的$routeMiddleware中注册别名,如:'menu.auth' => \App\Http\Middleware\MenuPermissionCheck::class - 找到菜单对应的实际路由定义位置——通常在
routes/admin.php或通过config/admin.php的route.middleware配置全局中间件;若需单独控制某菜单,建议显式重写其路由并绑定中间件
菜单权限与路由权限保持一致
菜单项的 permission 字段(如 'users.index')应和后台权限系统中定义的权限 slug 完全一致。Laravel-admin 内置的 Permission 类会自动读取该字段做判断,但仅限于控制器内调用 Permission::check() 场景。菜单本身不自动拦截,所以必须靠中间件补全这一环。
- 确保权限 slug 在「权限管理」页面已创建,并正确分配给角色
- 菜单配置示例中:
'Users'=> [ 'route'=>'admin.users.index', 'permission'=>'users.index' ],这个users.index就是中间件里要校验的值 - 若菜单使用子菜单或动态生成,权限校验逻辑需适配多级结构,比如检查父级权限或通配符匹配(
users.*)
避免中间件重复或遗漏的实操要点
常见错误是给整个 admin 路由组加了 admin.permission 中间件,但又在菜单路由上额外叠加自定义中间件,导致重复校验或冲突。应统一策略:
- 推荐做法:移除全局
admin.permission,改用自定义中间件统一接管所有菜单相关路由 - 对非菜单类接口(如 API、文件上传)保留独立鉴权逻辑,不混入菜单中间件
- 测试时务必手动访问菜单 URL(如
/admin/users),而非仅点菜单按钮,验证是否真正拦截 - 403 响应建议返回 Laravel-admin 默认的拒绝页面,保持 UI 一致性,不要跳转或抛异常中断流程


















