vsrklabs / laravel-permission-mongodb
为Laravel 5.2及以上版本使用mongodb进行权限处理
Requires
- php: ^8.1
- illuminate/auth: ^10.0
- illuminate/container: ^10.0
- illuminate/contracts: ^10.0
- mongodb/laravel-mongodb: ^4.0
Requires (Dev)
- monolog/monolog: ^3.2
- orchestra/testbench: ^8.0
- phpunit/phpunit: ^9.5.10
- squizlabs/php_codesniffer: ^3.7
This package is auto-updated.
Last update: 2024-09-27 14:50:49 UTC
README
此包允许您在数据库中管理用户权限和角色。它受到laravel-permission的启发。代码相同,功能相同,但它与laravel-mongodb兼容
安装后,您可以进行如下操作
// Adding permissions to a user $user->givePermissionTo('edit articles'); // Adding permissions via a role $user->assignRole('writer'); $role->givePermissionTo('edit articles');
如果您使用多个守卫,我们也有相应的支持。每个守卫将有自己的权限和角色集,可以分配给守卫的用户。请参阅readme中的使用多个守卫部分。
因为所有权限都会注册在Laravel的gate上,所以您可以使用Laravel默认的can
函数测试用户是否有权限
$user->can('edit articles');
目录
安装
Laravel 兼容性
Laravel
您可以通过composer安装此包
对于laravel 10.x, 9.x使用
composer require vsrklabs/laravel-permission-mongodb
对于laravel 8.x及更早版本使用
composer require vsrklabs/laravel-permission-mongodb:"^3.1"
您可以使用以下命令发布迁移
php artisan vendor:publish --provider="Maklad\Permission\PermissionServiceProvider" --tag="migrations"
php artisan migrate
您可以使用以下命令发布配置文件
php artisan vendor:publish --provider="Maklad\Permission\PermissionServiceProvider" --tag="config"
发布后,config/permission.php
配置文件包含
return [ 'models' => [ /* * When using the "HasRoles" trait from this package, we need to know which * Moloquent model should be used to retrieve your permissions. Of course, it * is often just the "Permission" model but you may use whatever you like. * * The model you want to use as a Permission model needs to implement the * `Maklad\Permission\Contracts\Permission` contract. */ 'permission' => vsrklabs\Permission\Models\Permission::class, /* * When using the "HasRoles" trait from this package, we need to know which * Moloquent model should be used to retrieve your roles. Of course, it * is often just the "Role" model but you may use whatever you like. * * The model you want to use as a Role model needs to implement the * `vsrklabs\Permission\Contracts\Role` contract. */ 'role' => vsrklabs\Permission\Models\Role::class, ], 'collection_names' => [ /* * When using the "HasRoles" trait from this package, we need to know which * table should be used to retrieve your roles. We have chosen a basic * default value but you may easily change it to any table you like. */ 'roles' => 'roles', /* * When using the "HasRoles" trait from this package, we need to know which * table should be used to retrieve your permissions. We have chosen a basic * default value but you may easily change it to any table you like. */ 'permissions' => 'permissions', ], /* * By default all permissions will be cached for 24 hours unless a permission or * role is updated. Then the cache will be flushed immediately. */ 'cache_expiration_time' => 60 * 24, /* * By default we'll make an entry in the application log when the permissions * could not be loaded. Normally this only occurs while installing the packages. * * If for some reason you want to disable that logging, set this value to false. */ 'log_registration_exception' => true, /* * When set to true, the required permission/role names are added to the exception * message. This could be considered an information leak in some contexts, so * the default setting is false here for optimum safety. */ 'display_permission_in_exception' => false, ];
Lumen
您可以通过Composer安装此包
composer require vsrklabs/laravel-permission-mongodb
复制所需的文件
cp vendor/vsrklabs/laravel-permission-mongodb/config/permission.php config/permission.php cp vendor/vsrklabs/laravel-permission-mongodb/database/migrations/create_permission_collections.php.stub database/migrations/2018_01_01_000000_create_permission_collections.php
您还需要在config/auth.php
中创建另一个配置文件。从Laravel仓库获取它或只需运行以下命令
curl -Ls https://raw.githubusercontent.com/laravel/lumen-framework/5.5/config/auth.php -o config/auth.php
然后,在bootstrap/app.php
中注册中间件
$app->routeMiddleware([ 'auth' => App\Http\Middleware\Authenticate::class, 'permission' => Maklad\Permission\Middlewares\PermissionMiddleware::class, 'role' => Maklad\Permission\Middlewares\RoleMiddleware::class, ]);
以及配置和服务提供者
$app->configure('permission'); $app->register(Maklad\Permission\PermissionServiceProvider::class);
现在,运行您的迁移
php artisan migrate
使用方法
首先,将Maklad\Permission\Traits\HasRoles
特性添加到您的User
模型中
use Illuminate\Auth\Authenticatable; use Jenssegers\Mongodb\Eloquent\Model as Model; use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Maklad\Permission\Traits\HasRoles; class User extends Model implements AuthenticatableContract, AuthorizableContract { use Authenticatable, Authorizable, HasRoles; // ... }
注意:如果您需要在其他模型(例如
Page
)中使用HasRoles
特性,您还需要在该模型中添加protected $guard_name = 'web';
,否则您将遇到错误
use Jenssegers\Mongodb\Eloquent\Model as Model; use Maklad\Permission\Traits\HasRoles; class Page extends Model { use HasRoles; protected $guard_name = 'web'; // or whatever guard you want to use // ... }
此包允许用户与权限和角色相关联。每个角色都与多个权限相关联。《角色》和《权限》是常规Moloquent模型。它们需要name
字段,可以像这样创建
use Maklad\Permission\Models\Role; use Maklad\Permission\Models\Permission; $role = Role::create(['name' => 'writer']); $permission = Permission::create(['name' => 'edit articles']);
可以使用以下方法之一将权限分配给角色
$role->givePermissionTo($permission); $permission->assignRole($role);
可以使用以下方法之一将多个权限同步到角色
$role->syncPermissions($permissions); $permission->syncRoles($roles);
可以使用以下方法之一从角色中删除权限
$role->revokePermissionTo($permission); $permission->removeRole($role);
如果您使用多个守卫,则需要设置guard_name
属性。请参阅readme中的使用多个守卫部分。
HasRoles
特性为您的模型添加 Moloquent 关系,可以直接访问或用作基本查询。
// get a list of all permissions directly assigned to the user $permissions = $user->permissions; // Returns a collection // get all permissions inherited by the user via roles $permissions = $user->getAllPermissions(); // Returns a collection // get all permissions names $permissions = $user->getPermissionNames(); // Returns a collection // get a collection of all defined roles $roles = $user->roles->pluck('name'); // Returns a collection // get all role names $roles = $user->getRoleNames() // Returns a collection;
HasRoles
特性还为您的模型添加了一个 role
范围,用于将查询范围限定到特定的角色或权限。
$users = User::role('writer')->get(); // Returns only users with the role 'writer' $users = User::permission('edit articles')->get(); // Returns only users with the permission 'edit articles'
范围可以接受一个字符串、一个 \Maklad\Permission\Models\Role
对象、一个 \Maklad\Permission\Models\Permission
对象或一个 \Illuminate\Support\Collection
对象。
使用“直接”权限
可以授予具有 HasRoles
特性的任何用户权限。
$user->givePermissionTo('edit articles'); // You can also give multiple permission at once $user->givePermissionTo('edit articles', 'delete articles'); // You may also pass an array $user->givePermissionTo(['edit articles', 'delete articles']);
可以从用户中撤销权限。
$user->revokePermissionTo('edit articles');
或者一次性撤销和添加新权限。
$user->syncPermissions(['edit articles', 'delete articles']);
可以测试用户是否有权限。
$user->hasPermissionTo('edit articles');
...或测试用户是否有多个权限。
$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);
保存的权限将注册到默认保护器的 Illuminate\Auth\Access\Gate
类中。因此,可以使用 Laravel 的默认 can
函数测试用户是否有权限。
$user->can('edit articles');
通过角色使用权限
可以将角色分配给任何用户。
$user->assignRole('writer'); // You can also assign multiple roles at once $user->assignRole('writer', 'admin'); // or as an array $user->assignRole(['writer', 'admin']);
可以从用户中移除角色。
$user->removeRole('writer');
角色也可以同步。
// All current roles will be removed from the user and replaced by the array given $user->syncRoles(['writer', 'admin']);
可以确定用户是否有特定的角色。
$user->hasRole('writer');
也可以确定用户是否有给定列表中的任何角色。
$user->hasAnyRole(Role::all());
也可以确定用户是否有给定列表中的所有角色。
$user->hasAllRoles(Role::all());
assignRole
、hasRole
、hasAnyRole
、hasAllRoles
和 removeRole
函数可以接受一个字符串、一个 \Maklad\Permission\Models\Role
对象或一个 \Illuminate\Support\Collection
对象。
可以将权限授予一个角色。
$role->givePermissionTo('edit articles');
可以确定一个角色是否有特定的权限。
$role->hasPermissionTo('edit articles');
可以从角色中撤销权限。
$role->revokePermissionTo('edit articles');
givePermissionTo
和 revokePermissionTo
函数可以接受一个字符串或一个 Maklad\Permission\Models\Permission
对象。
权限自动从角色继承。此外,还可以将个别权限分配给用户。
例如
$role = Role::findByName('writer'); $role->givePermissionTo('edit articles'); $user->assignRole('writer'); $user->givePermissionTo('delete articles');
在上面的例子中,一个角色被授予编辑文章的权限,并将此角色分配给了一个用户。现在,该用户可以编辑文章,并且还可以删除文章。删除文章的权限是用户的直接权限,因为它直接分配给了他们。当我们调用 $user->hasDirectPermission('delete articles')
时,它返回 true
,但对于 $user->hasDirectPermission('edit articles')
返回 false
。
此方法在为应用程序中的角色和用户设置权限表单时很有用,如果想要限制或更改用户的角色继承权限,即仅允许更改用户的直接权限。
可以列出所有这些权限。
// Direct permissions $user->getDirectPermissions() // Or $user->permissions; // Permissions inherited from the user's roles $user->getPermissionsViaRoles(); // All permissions which apply on the user (inherited and direct) $user->getAllPermissions();
所有这些响应都是 Maklad\Permission\Models\Permission
对象的集合。
如果我们遵循前面的例子,第一个响应将包含删除文章的权限集合,第二个将包含编辑文章的权限集合,第三个将包含两者。
使用Blade指令
此包还添加了 Blade 指令来验证当前登录用户是否具有给定列表中的所有或任何角色。
可选地,可以将要执行的检查的 guard
作为第二个参数传递。
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(Role::all()) 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(Role::all()) 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
或者
@if(auth()->user()->can('edit articles') && $some_other_condition) // @endif
使用多个守卫
当使用默认的 Laravel 身份验证配置时,所有上述方法都将自动正常工作,无需额外配置。
但是,当使用多个保护器时,它们将充当您权限和角色的命名空间。这意味着每个保护器都有自己的权限和角色集合,可以分配给其用户模型。
使用多个守卫的权限和角色
在创建新的权限和角色时,如果没有指定守卫,则将使用 auth.guards
配置数组中定义的第一个守卫。在为特定守卫创建权限和角色时,您需要在模型上指定其 guard_name
。
// Create a superadmin role for the admin users $user->hasPermissionTo('publish articles', 'admin');
注意:在确定给定模型上的角色/权限是否有效时,它会按照以下顺序选择守卫:首先检查模型的
$guard_name
属性;然后是配置中的守卫(通过提供者);接着是auth.guards
配置数组中定义的第一个守卫;最后是auth.defaults.guard
配置。
将权限和角色分配给守卫用户
您可以使用与上文在 通过角色使用权限 中描述的相同方法来分配权限和角色给用户。只需确保权限或角色上的 guard_name
与用户的守卫匹配,否则将抛出 GuardDoesNotMatch
异常。
使用多个守卫的Blade指令
您可以通过将您希望使用的守卫作为指令的第二个参数传入,来使用 使用 blade 指令 中列出的所有 blade 指令。
@role('super-admin', 'admin') I am a super-admin! @else I am not a super-admin... @endrole
使用中间件
此包包含 RoleMiddleware
和 PermissionMiddleware
中间件。您可以将它们添加到您的 app/Http/Kernel.php
文件中。
protected $routeMiddleware = [ // ... 'role' => \Maklad\Permission\Middlewares\RoleMiddleware::class, 'permission' => \Maklad\Permission\Middlewares\PermissionMiddleware::class, ];
然后您可以使用中间件规则来保护您的路由。
Route::group(['middleware' => ['role:super-admin']], function () { // }); Route::group(['middleware' => ['permission:publish articles']], function () { // }); Route::group(['middleware' => ['role:super-admin','permission:publish articles']], function () { // });
您可以通过在构造函数中设置所需的中间件类似地保护您的控制器。
public function __construct() { $this->middleware(['role:super-admin','permission:publish articles|edit articles']); }
您可以在 Laravel 异常处理器中添加一些内容。
public function render($request, Exception $exception) { if ($exception instanceof \Maklad\Permission\Exceptions\UnauthorizedException) { // Code here ... } return parent::render($request, $exception); }
使用Artisan命令
您可以使用 artisan 命令从控制台创建角色或权限。
php artisan permission:create-role writer
php artisan permission:create-permission 'edit articles'
在为特定守卫创建权限和角色时,您可以指定守卫名称作为第二个参数。
php artisan permission:create-role writer web
php artisan permission:create-permission 'edit articles' web
单元测试
在您应用程序的测试中,如果您没有在测试的 setUp()
部分中将角色和权限作为种子,那么您可能会遇到鸡生蛋的问题,因为角色和权限没有被注册到守卫中(因为您的测试是在守卫注册之后创建它们的)。解决这个问题很简单:在您的测试中简单地添加一个 setUp()
指令来重新注册权限,如下所示
public function setUp() { // first include all the normal setUp operations parent::setUp(); // now re-register all the roles and permissions $this->app->make(\Maklad\Permission\PermissionRegistrar::class)->registerPermissions(); }
数据库种子
有关数据库播种的几点说明
-
在播种之前最好清除
maklad.permission.cache
,以避免缓存冲突错误。这可以通过 Artisan 命令(见后面的“故障排除:缓存部分”)或直接在播种类中完成(见下面的示例)。 -
以下是一个示例播种器,它清除缓存,创建权限,然后将权限分配给角色
use Illuminate\Database\Seeder; use Maklad\Permission\Models\Role; use Maklad\Permission\Models\Permission; class RolesAndPermissionsSeeder extends Seeder { public function run() { // Reset cached roles and permissions app()['cache']->forget('maklad.permission.cache'); // create permissions Permission::firstOrCreate(['name' => 'edit articles']); Permission::firstOrCreate(['name' => 'delete articles']); Permission::firstOrCreate(['name' => 'publish articles']); Permission::firstOrCreate(['name' => 'unpublish articles']); // create roles and assign existing permissions $role = Role::firstOrCreate(['name' => 'writer']); $role->givePermissionTo('edit articles'); $role->givePermissionTo('delete articles'); $role = Role::firstOrCreate(['name' => 'admin']); $role->givePermissionTo(['publish articles', 'unpublish articles']); } }
扩展
如果您需要扩展现有的 Role
或 Permission
模型,请注意
- 您的
Role
模型需要扩展Maklad\Permission\Models\Role
模型 - 您的
Permission
模型需要扩展Maklad\Permission\Models\Permission
模型
如果您需要扩展或替换现有的 Role
或 Permission
模型,您只需要注意以下几点
- 您的
Role
模型需要实现Maklad\Permission\Contracts\Role
协议 - 您的
Permission
模型需要实现Maklad\Permission\Contracts\Permission
协议
在两种情况下,无论是扩展还是替换,您都需要在配置中指定您的新模型。为此,您必须在发布配置后更新配置文件中的 models.role
和 models.permission
值
php artisan vendor:publish --provider="Maklad\Permission\PermissionServiceProvider" --tag="config"
缓存
角色和权限数据被缓存以加快性能。
当您使用用于操作角色和权限的提供的方法时,缓存会自动为您重置
$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 maklad.permission.cache
缓存标识符
注意:如果您正在使用缓存服务,例如
redis
或memcached
,并且您的服务器上运行着其他网站,您可能会遇到缓存冲突。建议在每个应用程序中独特地设置自己的缓存前缀
在/config/cache.php
中,这样可以防止其他应用程序意外使用/更改您的缓存数据。
需要UI吗?
我们基于laravel-permission。此包默认不包含任何界面,您需要自行构建。要开始,请查看这篇详细的教程,作者是Caleb Oki。
变更日志
有关最近更改的更多信息,请参阅变更日志。
测试
composer test
贡献
安全性
如果您发现任何与安全相关的问题,请通过电子邮件dev.mostafa.maklad@gmail.com而不是使用问题跟踪器。
致谢
许可
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。