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 次