# 角色权限

houdunren.com @ 向军大叔

xj-small

laravel-permission 是使用广泛的Laravel 框架的基于角色的权限控制模块。

# 安装

composer require spatie/laravel-permission

#生成迁移文件,根据业务需要可以随意添加表字段
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"

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

php artisan migrate

# 基本使用

缓存角色和权限数据以加速性能。当你使用提供的方法来操作角色和权限时,缓存会自动为您重置:

$user->assignRole('writer');
$user->removeRole('writer');
$user->syncRoles(params);
$role->givePermissionTo('edit articles');
$role->revokePermissionTo('edit articles');
$role->syncPermissions(params);
$permission->assignRole('writer');
$permission->removeRole('writer');
$permission->syncRoles(params);

但是,如果直接在数据库中操作“权限/角色”数据而不是调用提供的方法,则除非手动重置缓存,否则不会在应用程序中看到反映的更改。

# 手动缓存重置

缓存角色和权限数据以加速性能。当你使用提供的方法来操作角色和权限时,缓存会自动为您重置。

要手动重置此软件包的缓存,请运行:

php artisan cache:forget spatie.permission.cache

代码删除缓存

app()['cache']->forget('spatie.permission.cache');

# 模型动作

User 等模型中引入 use Spatie\Permission\Traits\HasRoles 可以拥有所有权限操作方法

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
    ...
}

# 新建角色

use Spatie\Permission\Models\Role;
$role = Role::create(['name' => 'admin']);

# 删除角色

$user->removeRole('writer');

角色也可以同步:

//所有当前角色将从用户中删除,并替换为给定的数组中的角色
$user->syncRoles(['writer', 'admin']); 

# 添加权限

use Spatie\Permission\Models\Permission;

Permission::create(['name' => 'edit_articles']);
$role->givePermissionTo('edit_articles');

#或者使用下面分配权限
$permission->assignRole($role);

可以使用以下方法之一将多个权限同步到一个角色:

$role->syncPermissions($permissions);
$permission->syncRoles($roles);

# 删除权限

$role->revokePermissionTo($permission);
$permission->removeRole($role); 

一次性撤消并添加新的权限:

$user->syncPermissions(['edit articles', 'delete articles']);

# 添加用户角色

// 单个角色
$user->assignRole('admin');

// 数组形式的多个角色
$user->assignRole(['super_user', 'admin']);

// 同步角色(不存在添加,存在忽略)
auth()->user()->syncRoles(['admin']);

# 添加用户权限

// 为用户添加『直接权限』
$user->givePermissionTo('manage_contents');

//支持批量设置权限
$user->givePermissionTo(['manage_contents','add_site']);

// 获取所有直接权限
$user->getDirectPermissions() 

# 检查用户角色

// 是否是超级管理员
$user->hasRole('super_user');

// 拥有多个角色中的一个角色
$user->hasAnyRole(Role::all());  

// 包含所有角色
$user->hasAllRoles(Role::all()); 

# 检查权限

//用户是否拥有权限
$user->can('edit_articles'); 

//角色是否拥有权限
$role->hasPermissionTo('edit_articles');  

或者你可以传递一个代表权限 ID 的整数

$user->hasPermissionTo('1');
$user->hasPermissionTo(Permission::find(1)->id);
$user->hasPermissionTo($somePermission->id); 

如果用户有任何一个权限即通过:

$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);

用户必须拥有所有权限时通过:

$user->hasAllPermissions(['edit articles', 'publish articles', 'unpublish articles']);

你也可以传递整数以通过权限 ID 进行查找

$user->hasAnyPermission(['edit articles', 1, 5]);

使用 Laravel 默认的 can 功能测试用户是否拥有权限:

$user->can('edit articles');

# 获取用户权限

//获取直接分配给用户的所有权限的列表
$permissions = $user->getDirectPermissions();

//从用户角色继承的权限
$user->getPermissionsViaRoles();

//适用于用户的所有权限(继承和直接)
$permissions = $user->getAllPermissions();

# 获取用户角色

$roles = $user->getRoleNames(); // 返回一个集合

# 根据权限或角色获取用户

HasRoles 特征(trait)还为您的模型添加了一个“角色”范围,以便将查询范围限定为某些角色或权限:

仅返回具有角色 'writer' 的用户

$users = User::role('writer')->get(); 

仅返回具有 'edit articles' (继承或直接)权限的用户

$users = User::permission('edit articles')->get();

# Blade 和角色

测试一个特定的角色:

@role('writer')
    I am a writer!
@else
    I am not a writer...
@endrole

同上

@hasrole('writer')
    I am a writer!
@else
    I am not a writer...
@endhasrole

测试列表中的任何角色:

@hasanyrole($collectionOfRoles)
    I have one or more of these roles!
@else
    I have none of these roles...
@endhasanyrole
// or
@hasanyrole('writer|admin')
    I am either a writer or an admin or both!
@else
    I have none of these roles...
@endhasanyrole

测试所有角色:

@hasallroles($collectionOfRoles)
    I have all of these roles!
@else
    I do not have all of these roles...
@endhasallroles
// or
@hasallroles('writer|admin')
    I am both a writer and an admin!
@else
    I do not have all of these roles...
@endhasallroles

# Blade 和权限

此软件包不会添加任何特定于权限的 Blade 指令。 因此,使用 Laravel 原生的 @can 指令来检查用户是否具有某种权限。

@can('edit articles')
  //
@endcan

or

@if(auth()->user()->can('edit articles') && $some_other_condition)
  //
@endif