Laravel 用 spatie/laravel-permission 落地 RBAC:角色授权、权限缓存与中间件守门
test12026-10-200 次阅读
为什么不用 Policy/Gate 直接硬写
Gate 和 Policy 适合"某个用户可以删这篇帖子"这类点对点判断。当系统出现 admin、editor、viewer 多个角色,每个角色挂一堆权限时,再手写就容易散。spatie/laravel-permission 把"角色-权限-用户"这套 RBAC 抽象好,几行就能接上。
安装与迁移
装包后发布配置并建表,它会生成 roles、permissions、model_has_roles 等表。
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
给模型挂上 HasRoles
用户模型引入 trait 后即可使用 assignRole、givePermissionTo 等方法。
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use HasRoles;
}
初始化角色与权限
在 seed 里建权限、建角色、把权限授给角色,再把角色授给用户。
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
$edit = Permission::create(['name' => 'edit articles']);
$admin = Role::create(['name' => 'admin']);
$admin->givePermissionTo($edit);
$user->assignRole('admin');
在代码里判定
can 查权限、hasRole 查角色,语义清晰。
if ($user->can('edit articles')) {
// 允许编辑
}
if ($user->hasRole('admin')) {
// 管理员分支
}
Blade 与路由守门
模板里用 @can 控制按钮显隐,路由上用 can 中间件做第一道闸门,越权直接 403。
@can('edit articles')
<a href="#">编辑</a>
@endcan
Route::get('/articles/{id}/edit', [ArticleController::class, 'edit'])
->middleware('can:edit articles');
缓存是个隐藏坑
包默认把权限缓存到数组(甚至 Redis),线上改了角色权限后,旧缓存会让新规则不生效。改完记得清缓存:php artisan permission:cache-reset,或在代码里调用 Permission::all()->each->forgetCachedPermissions()。
小结
- 多角色多权限的系统用 RBAC 包比硬写 Gate 省心。
- HasRoles 让模型直接具备 assignRole / givePermissionTo。
- @can 与 can 中间件把"显隐"和"守门"两件事都接住。
- 权限改完务必清缓存,否则线上不生效。
T
test1
文章作者
为什么不用 Policy/Gate 直接硬写 Gate 和 Policy 适合"某个用户可以删这篇帖子"这类点对点判断...
- 分类
- 技术
- 发布时间
- 2026-10-20
- 字数
- 约 1509 字
- 阅读
- 0 次
