back2lobby / access-control
laravel 的角色和权限管理器
Requires
- php: ^8.1
- illuminate/auth: ^9.0|^10.0
- illuminate/cache: ^9.0|^10.0
- illuminate/collections: ^9.0|^10.0
- illuminate/container: ^9.0|^10.0
- illuminate/contracts: ^9.0|^10.0
- illuminate/database: ^9.0|^10.0
- illuminate/support: ^9.0|^10.0
- illuminate/validation: ^9.0|^10.0
Requires (Dev)
- laravel/pint: ^1.8
- orchestra/testbench: ^8.0
This package is auto-updated.
Last update: 2024-09-03 14:52:59 UTC
README
AccessControl 是一个 Laravel 扩展包,用于简单易用的角色和权限管理,支持基于模型的角色分配和基于角色的权限。
目录
点击展开
简介
AccessControl 通过允许基于模型分配角色和定义基于角色的权限,简化了角色和权限管理,以便对用户访问进行细粒度控制。
安装完成后,您可以简单地告诉 access-control 在入口处允许什么
// Give a role some permission AccessControl::allow("manager")->to('edit-company'); // Assign role to any user AccessControl::assign('manager')->to($user); // You can also assign role for a specific roleable model AccessControl::assign('manager',$company)->to($user); // Checking the permission on user for a roleable model AccessControl::canUser($user)->do("edit-company",$company); // Checking if the user has a role for that model AccessControl::is($user)->a("manager",$company);
安装
注意:AccessControl 需要 PHP 8.1+ 和 Laravel 9.0+
-
使用 composer 安装 AccessControl
composer require back2lobby/access-control
-
在用户模型中使用
HasRoles
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Back2Lobby\AccessControl\Traits\HasRoles; class User extends Authenticatable { use HasFactory, HasRoles // code here }
如果您想使用自定义用户模型而不是
App\Models\User
,请参阅 自定义用户模型 部分。 -
如果您有一个可分配角色的模型,则将 AccessControl 的特质添加到您的可分配角色模型中
use Back2Lobby\AccessControl\Traits\Roleable; class Post extends Model { use Roleable; }
-
现在,运行 AccessControl 的迁移。首先通过运行以下命令将迁移发布到您的应用
migrations
目录中php artisan vendor:publish --tag="access-control.migrations"
-
最后,运行迁移
php artisan migrate
安装完成后,您可以使用生成器为您的 Laravel 应用程序创建基本角色和权限。例如
use Illuminate\Database\Seeder; use Back2Lobby\AccessControl\Facades\AccessControlFacade as AccessControl; class AccessControlSeeder extends Seeder { public function run() { // Create all roles AccessControl::createManyRoles([ [ 'name' => 'admin', 'title' => 'Administrator', ], [ 'name' => 'editor', 'title' => 'Editor', ] ]); // Create all permissions AccessControl::createManyPermissions([ [ 'name' => 'create-post', 'title' => 'Create Post', 'description' => 'Allows user to create a new post', ], [ 'name' => 'edit-post', 'title' => 'Edit Post', 'description' => 'Allows user to edit an existing post', ], ]); } }
外观
每次在代码中使用 AccessControl
外观时,请记住在文件顶部添加此行到命名空间导入
use AccessControl;
如果您的 IDE 在此外观方面有任何问题,请使用 barryvdh/laravel-ide-helper
术语
角色
可以分配给用户的权限集。
权限
执行特定操作或访问特定资源的权利。
直接权限
直接允许或禁止角色直接拥有的权限。
间接权限
用户因具有超级权限而拥有的权限,而不是直接允许或禁止。
超级权限
用于授予所有权限,除了直接禁止的权限。
直接角色
如果角色直接允许权限,则该角色是权限的直接角色。
间接角色
如果角色不直接允许权限,而是因为具有超级权限而拥有该权限,则该角色是权限的间接角色。
用法
角色
创建角色
可以使用 createRole
方法创建角色。示例
$superAdmin = AccessControl::createRole([ 'name' => 'super-admin', 'title' => 'Super Admin' ]);
您还可以指定可分配的角色,这将限制为给定可分配的角色分配的角色。示例
AccessControl::createRole([ 'name' => 'manager', 'title' => 'Manager', 'roleables' => [Company::class] ]); // ✓ assigning role with allowed roleable will work fine $user->assign('manager',$company); // ✗ assigning role with roleable that's not allowed will throw error $user->assign('manager',$post);
可以一次创建多个角色,如下所示
AccessControl::createManyRole([ ['name','company-manager','tittle'=>'Company Manager'], ['name','company-user','title' => 'Company User'] ]);
更新角色
可以使用 updateRole
方法更新角色。示例
// using role name AccessControl::updateRole('author',[ 'name' => 'post-author', 'title' => 'Post Author' ]);
删除角色
可以使用 deleteRole
方法删除角色。示例
AccessControl::deleteRole('author');
获取角色
要检索一个角色,您可以使用方法 getRole
。示例
AccessControl::getRole('admin');
要检索所有可用的角色,我们可以执行以下操作以获取可用角色的集合。
AccessControl::getAllRoles();
允许权限
要允许特定权限的角色,您可以使用方法 allow
并将其与方法 to
连接。示例
AccessControl::allow('author')->to('edit'); // with permission name AccessControl::allow('author')->to($permission); // with permission object AccessControl::allow('author')->to(3); // with permission id
或者,我们还可以直接从角色模型本身使用 allow
方法,如下所示
$role->allow('create-post');
要间接(除了特定禁止外)允许所有可用的权限,可以使用 superPermission
方法,如下所示
AccessControl::allow('super-admin')->superPermission();
方法 superPermission
需要名为 *
的权限。如果它不可用,它将创建它。
拒绝权限
使用方法 disallow
从用户中撤销权限,并将其与方法 to
连接。示例
AccessControl::disallow('admin')->to('create admin');
或者,我们还可以直接从角色模型本身使用 disallow
,如下所示
$role->disallow('create-post');
要撤销分配给角色的超级权限,请使用方法 superPermission()
,如下所示
AccessControl::disallow('manager')->superPermission();
禁止权限
使用方法 forbid
并将其与方法 to
连接来禁止角色的权限。示例
AccessControl::forbid('manager')->to('delete company');
或者,我们还可以直接从角色模型本身使用 forbid
,如下所示
$role->forbid('create-post');
您可以使用方法 superPermission()
来间接禁止角色从所有权限中(除了特定允许外)。如下所示
AccessControl::forbid('manager')->superPermission();
获取角色的权限
要获取角色拥有的所有权限(包括允许和禁止),我们可以使用方法 getAllPermissionsOf
,如下所示
$permissions = AccessControl::getAllPermissionsOf('manager');
要获取角色的特定类型权限,我们可以使用方法 getAllowedPermissionsOf
、getDirectlyAllowedPermissionsOf
、getIndirectlyAllowedPermissionsOf
、getForbiddenPermissionsOf
、getDirectlyForbiddenPermissionsOf
、getIndirectlyForbiddenPermissionsOf
。示例
// getting allowed permissions $allowedPermissions = AccessControl::getAllowedPermissionsOf('manager'); $directlyAllowedPermissions = AccessControl::getDirectlyAllowedPermissionsOf('manager'); $indirectlyAllowedPermissions = AccessControl::getIndirectlyAllowedPermissionsOf('manager'); // getting forbidden permissions $forbiddenPermissions = AccessControl::getForbiddenPermissionsOf('manager'); $directlyForbiddenPermissions = AccessControl::getDirectlyForbiddenPermissionsOf('manager'); $indirectlyForbiddenPermissions = AccessControl::getIndirectlyForbiddenPermissionsOf('manager');
如果您不了解直接/间接权限,请阅读 术语。
分配角色
可以使用方法 assign
将角色分配给任何用户,并将其与 to
方法连接。或者,您可以直接在用户模型上使用可用的 assign
方法。示例
AccessControl::assign('admin')->to($user); // using facade $user->assign('editor'); // using user model
如果角色需要特定的可分配角色,您也可以指定它,如下所示。例如,您想要一个用户仅作为一个特定项目的经理。这可以通过以下方式实现
AccessControl::assign('manager',$project)->to($user); // using facade $user->assign('manager',$project); // using user model
撤销角色
可以使用方法 retract
从任何用户中撤销已分配的角色,并将其与 from
方法连接。示例
AccessControl::retract('admin')->from($user);
您还可以指定可分配的角色,仅撤销特定可分配角色的角色。例如,如果用户是多个公司的经理,则只会从用户中撤销给定公司的经理角色
AccessControl::retract('manager',$company)->from($user);
检查角色
要检查用户是否有特定角色,请使用方法 is
并将其与 a
或 an
方法连接。示例
AccessControl::is($user)->a('manager',$company); AccessControl::is($user)->an('admin');
要检查用户是否有特定角色,请将其与 notA
或 notAn
方法连接。示例
AccessControl::is($user)->notA('manager',$company); AccessControl::is($user)->notAn('admin');
要检查用户是否有所有给定角色,我们可以这样做
AccessControl::is($user)->all([ 'admin', 'manager' ]);
它不会检查任何角色可分配项,即使角色被限制在某些角色可分配项上。例如,如果用户拥有任何角色可分配项的经理角色,它将返回 true
AccessControl::is($user)->all([ 'manager' ]);
要检查用户是否有任何给定角色,我们可以这样做
AccessControl::is($user)->any([ 'admin', 'manager' ]);
重置角色
要从一个角色中移除所有权限,我们可以使用方法 resetRole
来重置它。示例
AccessControl::resetRole('admin');
权限
创建权限
可以使用方法 createPermission
创建权限。示例
AccessControl::createPermission([ 'name' => 'edit-post', 'title' => 'Edit Post' ]);
可以使用方法 createManyPermissions
一次创建多个权限,如下所示
AccessControl::createManyPermissions([ ['name' => 'create-post','title' => 'Create Post'], ['name' => 'edit-post','title' => 'Edit Post'], ['name' => 'delete-post','title' => 'Delete Post'] ]);
更新权限
可以使用方法 updatePermission
更新权限。例如,要将权限名称从 remove-post 更改为 delete-post,可以这样做:
AccessControl::updatePermission('remove-post',[ 'name' => 'delete-post', 'title' => 'Delete Post' ]);
删除权限
要删除权限,可以使用方法 deletePermission
,如下所示:
AccessControl::deletePermission('edit-post');
获取权限
要检索权限,可以使用方法 getPermission
,如下所示:
AccessControl::getPermission('delete-company');
要检索所有可用权限,请使用方法 getPermissions
。示例:
AccessControl::getPermissions();
获取具有权限的角色
要获取具有特定权限的所有角色,可以使用方法 getAllRolesOf
,如下所示:
$rolesWhoCanEdit = AccessControl::getAllRolesOf('edit-post');
要获取特定类型的角色,我们可以使用方法 getAllowedRolesOf
、getDirectlyAllowedRolesOf
、getIndirectlyAllowedRolesOf
、getForbiddenRolesOf
、getDirectlyForbiddenRolesOf
、getIndirectlyForbiddenRolesOf
。示例:
// getting allowed roles $allowedRoles = AccessControl::getAllowedRolesOf('edit-post'); $directlyAllowedRoles = AccessControl::getDirectlyAllowedRolesOf('edit-post'); $indirectlyAllowedRoles = AccessControl::getIndirectlyAllowedRolesOf('edit-post'); // getting forbidden roles $forbiddenRoles = AccessControl::getForbiddenRolesOf('edit-post'); $directlyForbiddenRoles = AccessControl::getDirectlyForbiddenRolesOf('edit-post'); $indirectlyForbiddenRoles = AccessControl::getIndirectlyForbiddenRolesOf('edit-post');
如果您不了解直接/间接角色,请参阅术语。
用户
获取用户角色
要获取用户分配的所有角色,可以使用由 Back2Lobby\AccessControl\Models\User
提供的方法 roles
。示例:
$roles = $user->roles()->get();
获取用户权限
要获取通过各种角色允许用户的所有权限,可以使用由 Back2Lobby\AccessControl\Models\User
提供的方法 permissions
。示例:
$roles = $user->permissions();
获取具有特定角色的用户
要获取具有特定角色的所有用户,可以使用由 Back2Lobby\AccessControl\Models\User
提供的静态方法 whereIs
。示例:
$admins = User::whereIs('admin')->get();
如果目标角色限制了一些角色化对象,可以这样做:
$players = User::whereIs('player',$team)->get();
您也可以通过使用角色模型中的 users
方法来反转逻辑
$admins = $adminRole->users()->get();
获取具有特定权限的用户
要获取具有特定权限的所有用户,可以使用由 Back2Lobby\AccessControl\Models\User
提供的静态方法 whereHas
。示例:
$users = User::whereHas('edit-post',$post)->get();
检查用户权限
要检查用户是否具有来自任何角色的特定权限,可以使用方法 canUser
并与方法 do
链接,如下所示:
$canCreatePost = AccessControl::canUser($user)->do('create-post');
您还可以这样指定角色化对象:
$canEditPost = AccessControl::canUser($user)->do('edit-post',$post);
重置用户
要从一个用户中移除所有角色,可以使用方法 resetUser
。示例:
AccessControl::resetUser($user);
功能
缓存
所有角色和权限都进行了缓存,并且每天自动刷新一次。这种优化提高了性能并减少了不必要的数据库查询。请注意,用户数据没有缓存,因为它会频繁更改。
您可以使用 sync
方法手动与数据库同步所有角色和权限。例如:
AccessControl::sync();
要清除缓存,可以使用方法 clearCache
,如下所示:
AccessControl::clearCache();
即使在清除缓存后,本地存储仍然会保留角色和权限,您也可以使用方法 reset
删除它们:示例
AccessControl::reset();
可以使用 cache
手动缓存存储:
AccessControl::cache();
注意:默认情况下,使用
file
作为缓存驱动程序,但可以在access.php
配置文件中更改。
授权
在 blade 文件中检查角色和权限时,我们可以在用户模型上使用 Laravel 内置的 can
方法。例如:
if($user->can('view-dashboard')){ // your code here }
如果您想检查特定模型上的权限,则可以这样做:
$user->can('edit-company',$company);
Blade 指令
类似地,在 blade 文件中检查角色和权限时,我们可以使用 Laravel 内置的 @can
指令来检查。例如:
@can('ban-users') <button class="btn btn-danger">Ban User</button> @endcan @can('edit-post',$post) <a href="{{ route('post.edit') }}">Edit Post</a> @endcan
配置文件
访问控制提供了一个配置文件,可以用于配置软件包的行为,包括指定缓存驱动程序和自定义用户模型。
您可以使用以下命令发布配置文件 access.php
:
php artisan vendor:publish --tag="access-control.config"
中间件
类似地,可以使用 Laravel 内置的 can
中间件:
Route::get('/dashboard', function () { return view('dashboard'); })->middleware('can:access-dashboard');
这将检查认证用户是否在处理请求之前具有访问-dashboard 权限。
您还可以使用 can
中间件来检查特定模型实例的权限。例如,以下路由将只针对具有在通过路由模型绑定传递给 /posts/{post}/edit
的 Post 模型实例上的 edit-post
权限的用户进行处理。
Route::get('/posts/{post}/edit', function () { return view('dashboard'); })->middleware('can:edit-post,' . Post::class);
在这种情况下,Post::class
被传递以指定需要进行权限检查的模型类。请注意,这仅在路由为Post模型设置了路由模型绑定时才有效。
自定义用户模型
默认情况下,此包使用App\Models\User
模型进行授权和认证。要使用自定义模型,需要以下步骤
- 在
access.php
中指定模型。例如:
'auth_user_model' => CustomUserModel::class
- 确保您的自定义用户模型继承自
Illuminate\Foundation\Auth\User
。 - 迁移与包相关的数据库表,或者使用以下命令获取一个新的数据库。
php artisan migrate:fresh
- 注意:请确保您已在
auth.php
配置文件中指定了守卫的新认证模型。例如:
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'customUsers', ], ], 'providers' => [ 'customUsers' => [ 'driver' => 'eloquent', 'model' => App\Models\CustomUserModel::class, ], ],