要让 laravel-admin 中不同角色看到不同的菜单,关键是从菜单数据源头控制——即每个角色登录后只加载被授权访问的菜单项;需在 config/admin.php 中将 'menu_model' 指向自定义模型(如 app\models\adminmenu),该模型继承 encore\admin\auth\database\menu 并重写 allnodes() 方法,根据当前用户角色关联的 menu.* 类型权限 slug 动态过滤菜单,菜单显示由权限而非角色名决定。

要让 Laravel-admin 中不同角色看到不同的菜单,关键不是简单隐藏按钮或跳过校验,而是从菜单数据源头控制——即让每个角色登录后,只加载它被授权访问的菜单项。
菜单数据来源可定制
Laravel-admin 默认从 admin_menu 表读取全部菜单,但这个行为可以替换。核心在于修改配置中菜单模型类:
- 在
config/admin.php中找到'menu_model'配置项 - 将其指向你自定义的菜单模型(如
App\Models\AdminMenu) - 该模型需继承
Encore\Admin\Auth\Database\Menu,并重写allNodes()方法
这样就能根据当前登录用户的角色动态筛选菜单节点,而不是全局静态加载。
按角色过滤菜单逻辑
在自定义菜单模型的 allNodes() 方法里,可结合 RBAC 关系做精准过滤:
- 先获取当前用户所有角色:
auth('admin')->user()->roles - 再查这些角色关联的所有权限(
permissions),提取其中标识为menu.*类型的权限 slug - 最后只返回
slug在该权限列表中的菜单项(例如menu.users、menu.posts)
示例权限命名建议:用点分隔,前缀统一为 menu.,如 menu.dashboard、menu.orders.edit,便于规则匹配和管理。
菜单与权限绑定操作
菜单本身不直接分配给角色,而是通过「权限」间接控制:
- 进入后台「权限管理」页面,新增权限,HTTP path 填菜单对应路由(如
/admin/users),slug 命名为menu.users - 在「角色管理」中,把
menu.users权限分配给「管理员」角色,不分配给「编辑」角色 - 无需改代码,只要用户没有该权限,其菜单就不会出现在左侧导航中
注意:菜单是否显示,取决于用户是否拥有对应 menu.xxx 权限,而不是角色名字符串比对。
避免常见陷阱
几个容易出错但影响明显的点:
- 权限缓存未清除:修改权限或角色后,运行
php artisan cache:forget spatie.permission.cache(若用了 Spatie 包)或清空 Laravel-admin 自带权限缓存 - 守卫(guard)不匹配:确保
auth('admin')正确生效,模板或中间件中不要混用Auth::user() - 菜单表字段缺失:自定义菜单模型时,确保数据库
admin_menu表含permission字段(用于存权限 slug),或在查询逻辑中用关联方式替代
不复杂但容易忽略,菜单差异化本质是「权限驱动渲染」,不是前端条件判断。











