管理角色/权限的两个最佳 Laravel 包
发布日期:作者: PovilasKorop
角色和权限是许多 Web 应用程序的重要组成部分。历史上,Laravel 针对角色和权限有很多包,并且也改进了核心代码。那么现在这个市场的情况如何呢?哪些包是最好的选择?我选了两个。
为什么需要包?
让我们从头开始——Laravel 有自己的 管理权限的核心逻辑。它是在 5.1.11 版本中引入的,自那以后几乎没有改变。我们有以下内容
- 门户 和 策略
- $this->authorize() 方法
- @can 和 @cannot Blade 命令
有人可能会说,拥有 Laravel 核心就足够了,不需要包。这是旧包被放弃的部分原因;核心功能取代了它们。
但是,仍然有一个领域是包可以提供帮助的——管理权限和角色,这在核心代码中并不容易。有两个包在这方面做得非常好,并且得到积极维护
特别提及:santigarcor/laratrust,它是未维护的 Entrust 的一个分支,可能是第三个强有力的竞争者。Laratrust 的问题是它用自己的命令替换了默认的 Laravel 命令,因此您将无法使用 Gates 或 @can 语法。相反,您需要使用 $user->can('edit-user') 或 @permission Blade 命令。但如果您不关心这些额外的语法部分,Laratrust 是一个很棒的包。它还具有团队功能,而 Spatie 和 Bouncer 包中没有。
还有其他一些选项,但它们似乎已经过时,而且没有那么活跃。尽管如此,您可能仍然希望关注它们,以防它们卷土重来
现在,让我们深入了解两个主要竞争者的“战役回顾”。
这些包究竟做了什么?
它们为您提供了一个 API,让您更轻松地处理角色和权限。此外,最终的代码更易读,更容易理解。
您可以使用 策略 和 门户 创建所有规则,这些规则将在几个不同的位置分散开来,您将拥有如下代码
$user->givePermissionTo('edit articles'); // Spatie package$user->allow('ban-users'); // Bouncer package
本质上,这两个包提供了非常相似的功能,但语法和数据库结构略有不同。让我们深入研究并进行比较。
安装和使用
这两个包的安装方式类似
- 添加到 composer 并安装。
- 将提供程序和外观 (Bouncer) 添加到 config/app.php 中。
- 发布并运行迁移。
- 将特殊特质添加到 User 模型中(这两个包都使用特质)。
- 就是这样;使用包的方法(必要时可以选择包含其类)。
包假设您已经有一个默认的 Laravel 用户数据库表,但没有用于角色/权限的任何结构。它们将添加自己的表和字段。
这两个包都有清晰的文档,并且没有任何问题。README 文件做得很好!
数据库结构
这是这两个包非常不同的一个地方。Spatie 的包有以下这些表
这里有一些解释
- 字段 guard_name 的默认值为 web**—**包允许使用多个守卫。
- 如您所见,有两个用于权限的中间表——一个用于角色,另一个用于用户。
- 字段 model_type 的默认值为 App\User,因此没有直接的外部键指向 users 表,也没有其他表具有 user_id 字段。
现在让我们看看 Bouncer 的数据库
差别很大,不是吗?而且关系更少。现在,让我解释一下
- Spatie 称为“权限”,Bouncer 称为“能力”。然后,“权限”表是附加到“实体”的一组能力。
- “实体”(在所有表中)是用于为其分配能力的对象。它可能是一个角色或一个用户。因此,没有直接关系指向 user_id 或 users 表;与 Spatie 的包一样。
- 还有一些字段与上一个包不同:abilities.title, abilities.only_owned, 和 roles.level。它们添加了一些额外的功能,但在 README 文件中没有得到很好的解释。
- Spatie 有 guard 字段,而 Bouncer 中没有。
总的来说,Bouncer 的数据库结构看起来稍微复杂一些,一开始也更难理解,但随之而来的是更大的灵活性。
可用方法
这些包确实提供了非常相似的功能,所以让我们详细比较一下。
创建角色/权限/能力
Spatie
您可以像使用 Laravel 的普通外观一样使用包的外观
use Spatie\Permission\Models\Role;use Spatie\Permission\Models\Permission; Role::create(['name' => 'writer']); Permission::create(['name' => 'edit articles']);
Bouncer
您可以创建角色和能力,以及在一句话中完成分配
Bouncer::allow('admin')->to('ban-users');
就是这样。在幕后,Bouncer 会为您创建一个 Role 模型和一个 Ability 模型。
但您也可以使用外观,
use Silber\Bouncer\Database\Ability;Ability::create(['name' => 'edit articles']);
如您所见,Bouncer 在这里具有更多功能,可以自动在幕后创建模型。
为用户分配角色
Spatie
$user->assignRole('writer');$user->assignRole(['writer', 'admin']); $user->removeRole('writer');
角色也可以同步
// All current roles will be removed from the user and replace by the array given$user->syncRoles(['writer', 'admin']);
Bouncer
$user->assign('admin');$user->assign(['writer', 'admin']); $user->retract('admin');
很棒的是,这两个包都接受单个角色或数组。
但 Spatie 的包在这里胜出,因为它具有 syncRoles 功能。这非常有用;使用 Bouncer,您需要通过几个操作手动执行。
为用户分配权限/能力
Spatie
$user->givePermissionTo('edit articles');$user->givePermissionTo('edit articles', 'delete articles'); $user->revokePermissionTo('edit articles');
Bouncer
$user->allow('ban-users');$user->allow(['ban-users', 'edit-articles']);
您可以将模型名称作为第二个参数传递。
Bouncer::allow($user)->to('edit', Post::class);Bouncer::allow($user)->to('edit', $post); $user->disallow('ban-users');Bouncer::disallow($user)->to('delete', Post::class);
类似的功能,但 Bouncer 提供了将模型类或其实例传递的能力。
检查用户的权限/角色
Spatie
检查角色
$user->hasRole('writer');$user->hasAnyRole(Role::all());$user->hasAllRoles(Role::all());
检查权限
$user->can('edit articles');$role->hasPermissionTo('edit articles');
Bouncer
检查角色
$user->isAn('admin');$user->isA('subscriber', 'editor');$user->isAll('editor', 'moderator');$user->isNot('subscriber', 'moderator');
检查权限
Bouncer::allows('edit articles')
这部分在两个包中非常相似,没有明显的赢家。
Blade 命令
Spatie
@role('writer') I'm a writer!@else I'm not a writer...@endrole
@hasanyrole('writer|admin') I have one or more of these roles!@else I have none of these roles...@endhasanyrole
Bouncer
Bouncer 不添加自己的 Blade 指令。
Spatie 的包功能更多。当然,对于这两个包,您都可以使用默认的 Laravel 命令,例如 @can 和 @endcan。
缓存
Spatie
角色和权限数据会自动缓存以提高性能。
要手动重置此包的缓存,请运行
php artisan cache:forget spatie.permission.cache
Bouncer
Bouncer 执行的所有查询都会针对当前请求进行缓存。如果启用跨请求缓存,则缓存将在不同的请求之间保持不变。
无论何时需要,您都可以完全刷新 Bouncer 的缓存
Bouncer::refresh();
或者,您也可以只刷新特定用户的缓存
Bouncer::refreshFor($user);
Bouncer 的缓存功能更加强大。启用/禁用缓存是一件好事,刷新特定用户的缓存可能很方便。
总体结论
如果你仍然期望在这里有一个明显的赢家,那是不可能的。这两个包都非常好,最终取决于你的偏好。
它们在某些功能上都有优势,但更多的是细节问题。
Spatie 的优势
- 文档略好(README 中未提及一些 Bouncer 的方法)
- 数据库结构更容易理解
- 使用 syncRoles() 方法而不是删除-插入方式
- 几个 blade 命令 - @role 和 @hasanyrole
- 能够使用多个守卫
Bouncer 的优势
- 创建角色/权限并分配它们 - 一句话搞定
- 允许或禁止基于模型或其实例的权限
- 缓存机制略好
- 数据库结构更健壮,包含几个更有用的字段
如果这些细节对你来说非常重要,那么这可能是你的选择原因。否则,选择 Spatie 或 Bouncer,你不会失望。
附赠礼物
最后,这两个包都提供了一套管理角色和权限的功能,但没有 UI 或管理面板来管理它们。我已经准备了一个基于这两个包的 UI 启动套件。你可以把它用作管理角色和权限的模板。
以下是 GitHub 存储库的链接