kodilab / laravel-batuta
Laravel 权限
Requires
- php: >=7.0
- illuminate/database: ^6.0
- illuminate/support: ^6.0
Requires (Dev)
- fzaninotto/faker: ^1.4
- orchestra/testbench: ^4.0
- phpunit/phpunit: ^8.0
This package is auto-updated.
Last update: 2020-04-08 12:48:03 UTC
README
laravel-batuta
是一个 Laravel 包,它提供了一个与 Laravel 提供的 Authorization
系统兼容的权限解决方案。
一些概念
laravel-batuta
使用一些概念,在使用此包之前必须理解。
让我们用一个电子商务项目的例子来说明。您的网站正在销售 商品。那么 item
是 资源 的一个明显例子。在这些 资源 上,我们将能够执行 操作。我们可以为每个资源创建尽可能多的操作。在这种情况下,我们可以列出以下操作(由 verb
+ resource
组成)
- 读取商品
- 写入商品
- 删除商品
- 更新商品价格
请注意,我们将 update-price
从 write
中提取出来作为一个独立操作。这允许我们定义可以更新商品但不可更新其价格的用户,可以只更改价格的用户,以及可以执行这两个操作的用户。您可以为每个资源创建哪些操作以及多少操作取决于您的需求!
然后,用户 将对每个 操作 拥有权限。这种权限可以是 true
(可以执行该操作),false
(不能执行该操作)。如果用户对操作的权限未定义,则默认为 false
。
为了便于管理权限组,您可以给 用户 分配一个 角色。然后,用户 将在权限未定义时继承分配的角色权限。
总结一下,用户 属于一个(或多个)角色。用户和角色都对 操作 拥有权限。当用户没有权限时,检查用户所属的任何角色是否有此权限。
安装
首先,在您的 composer 配置中添加 laravel-batuta
依赖项
composer require kodilab/laravel-batuta
一旦将依赖项添加到项目中,您必须发布所需的迁移。这些迁移将创建 laravel-batuta
所需的表。还将创建基本的 初始角色。使用以下命令生成迁移文件
php artisan batuta:install
可选地,如果您想修改参数(例如,laravel-batuta
将要创建的表名或初始角色名),您可以生成一个配置文件。您可以使用此命令完成此操作
php artisan batuta:config
这将生成配置文件到您的配置目录(config/batuta.php
)。此配置文件包含每个参数的解释。所以,如果您想改变一些东西,在开始之前看看它。
一旦配置符合您的需求,就是时候运行迁移了。
php artisan migrate
恭喜,laravel-batuta
已安装并配置好,可以使用了!
BatutaBuilder
以下部分建议使用 BatutaBuilder
。此类提供了一些管理 actions
和 roles
的辅助方法。重要的是要知道,所有这些方法在底层都直接使用 QueryBuilder
,以避免实例化 Eloquent Models
。这使得我们可以在 migration
文件中无任何问题地使用 BatutaBuilder
。
请注意,它们不会触发 Eloquent ORM
事件。如果您想使用 Eloquent ORM
的功能,请使用 Eloquen
提供的 create()
和 delete()
方法来管理 actions
和 roles
。
操作
如 概念部分 中所述,操作代表用户可以对资源执行的操作。在前面的示例中,一个项的操作可以是,例如,create
、read
、write
。我们可以创建更具体的操作来限制授权,如:update-price
、delete
、update-images
。
这些操作总是与一个 resource
相关联。因此,在这种情况下,这些 actions
的名称将是 create item
、read item
、write item
、update-price item
、update-images item
等...
创建和删除操作
所有这些操作都必须在 action
表中创建和持久化,才能使用。您可以使用 BatutaBuilder
辅助方法来创建操作。在下面的示例中,我们使用迁移文件,但您可以使用您喜欢的任何方法。
use Kodilab\LaravelBatuta\Builder\BatutaBuilder;
class CreateBatutaPermissionsTables extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
BatutaBuilder::createAction('update-price', 'item', 'Can change the item price')
}
/**
* Reverse the migrations.
*/
public function down()
{
BatutaBuilder::removeAction('update-price', 'item');
}
}
public static function createAction(string $verb, string $resource, string $description = null)
创建一个新的操作。在创建之前,verb
和 resource
将被 slugged
。例如,如果 verb='update price'
和资源 Item
,则生成的以下 action
为:
verb
: 'update-price'resource
: 'item'name
: 'update-price item'
public static function removeAction(string $verb, string $resource = null)
根据操作的 verb
和 resource
删除现有操作。
检索操作
public static function findByName(string $name)
根据名称检索操作
- string $name: 操作的
name
。
返回
- 操作实例或不存在时为 null
Actions::findByName('update-price item');
角色
角色是一组授予的权限。您可以给一个用户分配多个角色,也可以给一个角色分配多个用户(多对多关系)。默认情况下,当用户属于某个角色时,任何未为用户定义的权限将继承该角色的权限。例如,如果update-price item
未在用户权限列表中定义,则会检查是否有任何角色授予了update-price item
。这种行为可以针对任何用户和角色的案例进行更改(请参阅禁用权限继承)。
初始角色
默认情况下,当您运行migrations
时,laravel-batuta
会创建两个初始角色
。您可以在运行迁移之前通过更改配置文件中的名称来自定义其角色名称。如果之后想要更改它,则可以通过更新模型或更改数据库中的内容来实现。
这些角色很重要,因为它们都有一些“特殊”的行为
-
默认角色:默认角色将在创建用户或用户没有角色(至少,必须为用户分配一个角色)时默认分配给用户。这仅在您为用户模型启用角色时发生。此角色不能被删除。
-
上帝角色:上帝角色是一个特殊角色。属于此角色的每个用户都将被授予执行任何操作的权利。无论您是否更改了该用户或该角色的权限。它将始终拥有全部授权权限。此角色不能被删除。
创建和删除角色
您可以使用BatutaBuilder
来管理角色
,就像创建操作
一样。
use Kodilab\LaravelBatuta\Builder\BatutaBuilder;
class CreateBatutaPermissionsTables extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
BatutaBuilder::createRole('editor')
}
/**
* Reverse the migrations.
*/
public function down()
{
BatutaBuilder::removeRole('editor');
}
}
createRole(string $name)
创建一个新的角色。
removeRole(string $verb, string $resource)
根据名称删除一个现有的角色。
分配和解除用户角色
为了分配角色给用户并解除它们,您必须将HasRoles
特性添加到User
模型中
class User extends Model
{
use HasRoles;
}
添加此特性后,您可以使用以下方法
addRole(Role $role)
添加一个新角色,如果尚未添加,则添加到用户中。一旦角色被添加到用户中,它将继承该角色的权限。
- Role $role:要分配的
Role
实例。
use Kodilab\LaravelBatuta\Models\Role;
...
$role = Role::find(1);
$user->addRole($role);
public function bulkRoles(array $roleIds, bool $detaching = false)
添加一组角色。
- array $roleIds:包含
Role
ID的数组。 - bool $detaching = false:如果
detaching = true
,则删除用户分配的先前角色。
$roles = [1, 2];
$user->bulkRoles($roles, true);
public function removeRole(Role $role)
从用户的分配中删除一个角色。
- Role $role:要分配的
Role
实例。
$role = Role::find(1);
$user->addRole($role);
$user->removeRole($role);
public function belongsToRole(Role $role)
判断一个角色是否分配给用户
- Role $role:要分配的
Role
实例。
返回
true
:用户属于此角色false
:用户不属于此角色
$user->belongsToRole($other);
公共函数 isGod()
返回用户是否属于 god 角色:
返回:
true
:用户属于god 角色'
false
:用户不属于god 角色'
$user->isGod();
授予权限
尽管 Role
已经准备好使用,但还需要对 User
模型进行更改,以便为用户提供权限。您应该添加 UserPermissions
特性和实现 Permissionable
接口。
class User extends Model implements Permissionable
{
use UserPermissions;
}
这将向 User
提供处理权限的新方法。
此处列出的方法可用于 Roles
和 Users
。
授予用户或角色的权限
updatePermission(Action $action, bool $grant): void
为特定操作授予用户/角色的权限。
- Kodilab\LaravelBatuta\Models\Action|string $action:动作实例或动作名称
- bool $grant:
true|false
use Kodilab\LaravelBatuta\Models\Action;
...
$action = Action::findByName('update-price item');
if (!is_null($action)) {
$user->updatePermission($action, true);
}
您可以使用动作 name
而不是动作实例
$user->updatePermission('update-price item', true);
bulkPermissions(array $permissions, bool $detaching = false): void
为用户/角色授予多个权限。
- array $permissions:关联数组,其中
key
是动作id
,value
是true|false
。 - bool $detaching = false:如果
detaching = true
,则将删除分配给用户的先前权限。
$permissions = [
1 => true,
2 => false
];
$user->bulkPermissions($permissions, true);
检索用户或角色的权限
hasPermission(Action|string $action): bool
返回是否有权限。如果权限未定义,则返回 false
。如果正在使用 hasRoles
特性,当权限未定义时,则将检查所属角色的权限。
- Kodilab\LaravelBatuta\Models\Action|string $action:动作实例或动作名称
返回
true
:用户可以执行该操作false
:用户 不能 执行该操作
$action = Action::get('update-price item');
if($user->hasPermission($action)) {
$item->changePrice();
}
禁用权限继承
有时您可能想要禁用权限继承(用户从其角色继承权限)。您可以通过添加方法 private function shouldInheritPermissions()
来做到这一点。该方法应根据您是否希望继承权限返回 true
或 false
。例如
class User extends... {
...
private function shouldInheritPermissions()
{
if ($this->id === 1) {
return false;
}
return true;
}
}
id=1 的用户无论属于哪些角色都不会继承权限。其他用户将按预期继承权限。
重要:属于 god 角色的
用户将不受 shouldInheritPermissions()
方法的影响。