关于 laravel-permission
面向 Laravel 开发者的 Spatie Laravel Permission 参考技能,用于设计基于角色和权限的访问控制。内容涵盖多租户团队、路由与界面授权、API 集成及测试。
主要功能
- 01配置角色与权限的 RBAC
- 02通过中间件和 Blade 控制访问
- 03支持团队范围与通配符权限
- 04集成 Policy、API Guard 和 Sanctum
- 05提供缓存、查询范围与事件审计指南
- 06涵盖自定义模型和测试模式
适用场景
- 01为 Laravel 路由配置角色或权限限制
- 02按租户团队管理角色和权限
- 03为 API 与 Policy 接入权限检查
- 04测试权限变更并管理权限缓存
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fusengine/ agents --skill laravel-permission安装后在 Claude Code 中输入/laravel-permission确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-usage.mdartisan-commands.mdblade-directives.mdcache.mdcustom-models.mddirect-permissions.mdevents.mdmiddleware.mdperformance.mdpolicies.mdquery-scopes.mdspatie-permission.mdsuper-admin.mdteams.mdreferences/templates/ApiExceptionHandler.php.mdApiPermissionSetup.php.mdApiUserResource.php.mdBladeExamples.blade.mdCacheConfig.php.mdControllerMiddleware.php.mdCustomPermission.php.mdCustomRole.php.mdDeployScript.sh.mdPermissionAudit.php.mdPermissionEventListener.php.mdPermissionSeeder.php.mdPermissionTest.php.mdPostPolicy.php.mdRoleSeeder.php.mdroutes-example.md详细介绍
涵盖 Spatie Laravel Permission 的基于角色的访问控制:角色和权限、路由中间件、Blade 授权指令、多租户团队范围、通配符/层级权限、超级管理员绕过、缓存管理、直接权限与角色权限继承、查询范围、基于事件的审计日志、Policy 集成、Sanctum/Passport API 用法、自定义模型(支持 UUID)以及测试模式。
Laravel Permission (Spatie)
Agent 工作流(强制)
在进行任何实现之前,并行启动 3 个 Agent,每个 Agent 调用一次,并指定 name:
- fuse-ai-pilot:explore-codebase - 检查现有的身份验证模式
- fuse-ai-pilot:research-expert - 通过 Context7 核实 Spatie Permission 文档
- mcp__context7__query-docs - 检查 Laravel 授权模式
实现完成后,运行 fuse-ai-pilot:sniper 进行验证。
概览
Spatie Laravel Permission 为 Laravel 应用提供完整的基于角色的访问控制(RBAC)。
| 组件 | 用途 |
|---|---|
| Role | 权限组(admin、writer) |
| Permission | 单项能力(编辑文章) |
| Middleware | 路由保护 |
| Blade Directives | UI 授权 |
| Teams | 多租户范围 |
| Wildcards | 层级权限 |
| Super Admin | 绕过所有检查 |
| Events | 审计日志(v6.15.0+) |
| Query Scopes | 按角色/权限筛选用户 |
| API Support | Sanctum/Passport 集成 |
| Policies | 基于资源的授权 |
关键规则
- 在
DatabaseSeeder中填充角色/权限 - 更改后重置缓存:
php artisan permission:cache-reset - 使用 kebab-case 命名:
edit-articles - 控制器中绝不要硬编码角色检查——使用中间件
- 多租户应用应尽早设置团队上下文
- 为 API 指定 guard——
permission:edit,api - 在测试中清除缓存——在 setUp()/beforeEach() 中重置
参考指南
核心概念
| 主题 | 参考资料 | 何时查阅 |
|---|---|---|
| Setup | spatie-permission.md | 安装、模型设置、核心方法 |
| Middleware | middleware.md | 路由保护模式 |
| Blade | blade-directives.md | UI 授权指令 |
| Direct vs Role | direct-permissions.md | 权限继承 |
高级功能
| 主题 | 参考资料 | 何时查阅 |
|---|---|---|
| Teams | teams.md | 多租户权限 |
| Wildcards | wildcard-permissions.md | 层级模式 |
| Super Admin | super-admin.md | 绕过所有权限 |
| Custom Models | custom-models.md | UUID、扩展模型 |
集成
| 主题 | 参考资料 | 何时查阅 |
|---|---|---|
| API Usage | api-usage.md | Sanctum、guards、JSON 响应 |
| Policies | policies.md | Laravel Policy 集成 |
| Query Scopes | query-scopes.md | User::role()、User::permission() |
| Events | events.md | 审计日志、通知 |
运维与质量
| 主题 | 参考资料 | 何时查阅 |
|---|---|---|
| Cache | cache.md | 性能、调试 |
| CLI | artisan-commands.md | Artisan 命令 |
| Testing | testing.md | 测试、工厂、设置 |
| Performance | performance.md | 优化、N+1、缓存 |
模板(代码示例)
设置与播种
| 模板 | 用途 |
|---|---|
| UserModel.php.md | 带有 HasRoles trait 的用户模型 |
| RoleSeeder.php.md | 基本角色播种 |
| PermissionSeeder.php.md | 权限创建播种器 |
| WildcardSeeder.php.md | 分层权限 |
路由与中间件
| 模板 | 用途 |
|---|---|
| routes-example.md | 受保护路由示例 |
| ControllerMiddleware.php.md | 控制器中的中间件 |
| BladeExamples.blade.md | Blade 指令示例 |
团队与多租户
| 模板 | 用途 |
|---|---|
| TeamMiddleware.php.md | 多租户中间件 |
| TeamSeeder.php.md | 团队范围角色播种器 |
| TeamModel.php.md | 带有 boot 的团队模型 |
超级管理员与缓存
| 模板 | 用途 |
|---|---|
| SuperAdminSetup.php.md | Gate::before 绕过 |
| CacheConfig.php.md | 缓存配置 |
| DeployScript.sh.md | CI/CD 缓存管理 |
API 集成
| 模板 | 用途 |
|---|---|
| ApiPermissionSetup.php.md | API guard + Sanctum |
| ApiExceptionHandler.php.md | JSON 错误响应 |
| ApiUserResource.php.md | 带有权限的用户资源 |
策略与事件
| 模板 | 用途 |
|---|---|
| PostPolicy.php.md | 与 Spatie 集成的策略 |
| PermissionEventListener.php.md | 审计事件监听器 |
| UserQueryExamples.php.md | 查询作用域示例 |
| PermissionAudit.php.md | 审计服务 |
测试
| 模板 | 用途 |
|---|---|
| PermissionTest.php.md | Pest 与 PHPUnit 测试 |
| UserFactory.php.md | 带有权限状态的工厂 |
自定义模型
| 模板 | 用途 |
|---|---|
| CustomRole.php.md | 扩展的 Role 模型 |
| CustomPermission.php.md | 扩展的 Permission 模型 |
| UUIDMigration.php.md | UUID 表迁移 |
| SetupPermissions.php.md | 自定义 artisan 命令 |
快速参考
分配角色
$user->assignRole('admin');
检查权限
$user->can('edit articles');
中间件(Web)
Route::middleware(['role:admin'])->group(fn () => ...);
中间件(API)
Route::middleware(['auth:sanctum', 'permission:edit,api'])->group(fn () => ...);
Blade
@role('admin') ... @endrole
@can('edit articles') ... @endcan
查询作用域
User::role('admin')->get();
User::permission('edit articles')->get();
团队
setPermissionsTeamId($team->id);
通配符
$role->givePermissionTo('articles.*');
超级管理员
Gate::before(fn ($user, $ability) =>
$user->hasRole('Super-Admin') ? true : null
);
测试
beforeEach(fn () => app(PermissionRegistrar::class)->forgetCachedPermissions());
功能矩阵
| 功能 | 状态 | 参考 |
|---|---|---|
| 基本 RBAC | ✅ | spatie-permission.md |
| 中间件 | ✅ | middleware.md |
| Blade 指令 | ✅ | blade-directives.md |
| 多守卫(web/api) | ✅ | middleware.md, api-usage.md |
| 团队(多租户) | ✅ | teams.md |
| 通配符权限 | ✅ | wildcard-permissions.md |
| 超级管理员 | ✅ | super-admin.md |
| 缓存管理 | ✅ | cache.md |
| 直接权限与角色权限 | ✅ | direct-permissions.md |
| Artisan 命令 | ✅ | artisan-commands.md |
| UUID 支持 | ✅ | custom-models.md |
| 自定义模型 | ✅ | custom-models.md |
| 事件(v6.15.0+) | ✅ | events.md |
| 查询作用域 | ✅ | query-scopes.md |
| 策略集成 | ✅ | policies.md |
| API / Sanctum | ✅ | api-usage.md |
| 测试 | ✅ | testing.md |
| 性能 | ✅ | performance.md |
Laravel 13 说明
Spatie Permission 8.x(当前版本为 8.3,要求 PHP 8.3+ 和 Laravel 12/13)兼容 Laravel 13。L13 集成:
- 从 v6 升级至 v7,再升至 v8:事件类以
Event结尾(RoleAttachedEvent…),命令以Command结尾,clearClassPermissions()已移除,findByName()/findOrCreate()接受BackedEnum|string(v8)——参见 events.md - 缓存:
permission.cache.key键在config/permission.php中保持显式设置(spatie.permission.cache)→ 不受 L13 改用连字符前缀的影响 - 控制器属性:组合使用
#[Authorize](策略)和#[Middleware('role:admin')](RBAC),命名空间为Illuminate\Routing\Attributes\Controllers——参见 [[laravel-blade]] - PHP 8.3:为自定义 Role/Permission DTO 使用
final readonly class
#[Middleware(['auth', 'role:admin|editor'])]
#[Authorize('update', 'post')]
public function update(UpdatePostRequest $request, Post $post) { /* ... */ }
最佳实践
应该做
- 定义唯一事实来源:策略或权限(二者不能同时用于同一操作)
- 使用
permission:create-post(动词-名词)以保持清晰 - 仅在确有多租户需求时启用
teams - 按用户缓存权限(
Cache::remember('user.permissions.'.$id, ...)) - 通过
Gate::before()实现超级管理员权限(不要使用*通配符权限)
不应该做
- 将权限存储在会话中(使用 Spatie 缓存)
- 在缺乏一致架构的情况下混用
hasRole()和hasPermissionTo() - 在代码中硬编码角色名称(使用
RoleEnum枚举) - 忘记在 Seeder 中调用
assignRole()后清除缓存 - 向超级管理员授予
*(优先使用有针对性的Gate::before())
评论
支持 Markdown