PHP项目Spatie权限包用法

wen PHP项目 2

Spatie 权限包使用指南

安装配置

composer require spatie/laravel-permission

生成配置文件和数据迁移:

PHP项目Spatie权限包用法

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate

模型设置

// app/Models/User.php
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
    use HasRoles;
    // ...
}

基本用法

创建和管理角色与权限

// 创建权限
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;
// 创建权限
Permission::create(['name' => 'edit articles']);
Permission::create(['name' => 'publish articles']);
Permission::create(['name' => 'delete articles']);
// 创建角色并赋予权限
$role = Role::create(['name' => 'writer']);
$role->givePermissionTo('edit articles');
$role->givePermissionTo('publish articles');
// 创建超级管理员角色
$adminRole = Role::create(['name' => 'super-admin']);
$adminRole->givePermissionTo(Permission::all());
// 给用户分配角色
$user = User::find(1);
$user->assignRole('writer');
// 或直接分配权限
$user->givePermissionTo('edit articles');

权限检查

// 检查用户权限
$user->hasPermissionTo('edit articles'); // true/false
$user->can('edit articles'); // 使用Laravel Gate
// 检查用户角色
$user->hasRole('writer'); // true/false
$user->hasAnyRole(['writer', 'admin']); 
$user->hasAllRoles(['writer', 'admin']);
// 检查通过角色获得的权限
$user->can('publish articles'); // 如果属于writer角色且有该权限则返回true
$user->hasAnyPermission(['edit articles', 'publish articles']);
$user->hasAllPermissions(['edit articles', 'publish articles']);

在中间件中使用

// 路由中使用
Route::group(['middleware' => ['role:admin']], function () {
    // 只有admin角色可访问
});
Route::group(['middleware' => ['permission:publish articles']], function () {
    // 有publish articles权限的用户可访问
});
Route::group(['middleware' => ['role:admin|writer']], function () {
    // admin或writer角色可访问
});
// 多个权限检查
Route::group(['middleware' => ['permission:edit articles|publish articles']], function () {
    // 有任一权限即可
});

Blade模板中使用

@role('writer')
    我拥有writer角色
@endrole
@hasrole('admin')
    我拥有admin角色
@endhasrole
@can('edit articles')
    我可以编辑文章
@endcan
@canany(['edit articles', 'publish articles'])
    我有编辑或发布权限
@endcanany
@unlessrole('writer')
    我不是writer角色
@endunlessrole
@haspermission('delete articles')
    我可以删除文章
@endhaspermission

高级用法

判断角色和权限的组合

// 用户有某个角色 有某个权限
$user->hasRole('admin') && $user->hasPermissionTo('edit articles');
// 直接获取用户所有权限
$allPermissions = $user->getAllPermissions();
// 获取用户所有角色名
$roleNames = $user->getRoleNames();

数据库操作

// 更新角色权限
$role = Role::findByName('writer');
$role->syncPermissions(['edit articles', 'delete articles']);
// 移除权限
$role->revokePermissionTo('publish articles');
// 移除角色
$user->removeRole('writer');
// 同步用户角色
$user->syncRoles(['writer', 'admin']);

自定义Guard

// 创建带guard的角色/权限
$role = Role::create([
    'name' => 'admin',
    'guard_name' => 'admin'
]);
$permission = Permission::create([
    'name' => 'manage_admin_panel',
    'guard_name' => 'admin'
]);

常用辅助方法

// 列出所有权限
Permission::all();
// 列出所有角色
Role::all();
// 获取有特定权限的所有用户
$users = User::permission('edit articles')->get();
// 获取有特定角色的所有用户
$users = User::role('writer')->get();

最佳实践

// 建议在Seeding中创建基础角色和权限
// database/seeders/RoleAndPermissionSeeder.php
public function run()
{
    // 清理缓存
    app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
    // 创建权限
    Permission::create(['name' => 'create users']);
    Permission::create(['name' => 'edit users']);
    Permission::create(['name' => 'delete users']);
    // 创建角色并分配权限
    $adminRole = Role::create(['name' => 'admin']);
    $adminRole->givePermissionTo(Permission::all());
    $managerRole = Role::create(['name' => 'manager']);
    $managerRole->givePermissionTo(['create users', 'edit users']);
}

注意事项

  1. 缓存:修改权限后需要清除缓存

    app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
  2. 性能优化:对频繁查询权限的用户使用Eager Loading

    $users = User::with('roles.permissions')->get();
  3. 多语言:权限名称建议使用统一的命名规范,如 module.action

这个包非常适合需要复杂权限控制的PHP项目,特别是Laravel框架项目。

抱歉,评论功能暂时关闭!