“所以……我需要一个简单的授权。 某种管理员角色,也许是编辑者/主持人的角色。 现在谷歌它。 喔! laravel已经有现成的软件包!
zizaco /委托 ,
spatie / laravel许可等! 让我们选择一些吧!”
就是这样。 然后,程序包迁移将5个标签添加到数据库中,用于存储角色,权限及其关系。 所有授权规则(例如角色
“ admin”和
“ editor”都可以执行
“编辑帖子” )都存储在这些表中。 通常,一个项目有许多数据库副本。 开发人员,测试基础和生产的副本。 结果,所有这些授权规则都被强制在数据库之间同步。
我遇到了几个项目,其中生产数据库中有一个规则的主要副本,其余的则从那里复制了所有内容。
使用Seeder类(
示例 )的想法要好得多。 您只需要跑步
php artisan db:seed AuthSeeder
并且您在数据库中拥有最新版本的规则。 因此,这个播种者阶层成为一种单一的真理来源。 很好,但是这种方法仍然有很多不便之处:
- Seeder应该足够聪明,不仅可以创建角色和权限以及它们之间的连接,还可以同步旧版本。 即 必要时删除或创建角色和权限之间的链接。
- 规则存储在数据库中,并且它们之间需要不断同步。 对“编辑者不再应该编辑帖子,只能发布帖子”形式的要求的每次更改都会导致种子更改,通过git或其他方式同步代码库以及“不要忘记开始AuthSeeder!”。
- 授权规则可能很复杂。 例如,出版物不仅可以由编辑者或管理员进行编辑,还可以由该出版物的作者进行编辑。 因此,代替简单的中间件:
['middleware' => ['permission:edit posts']]
开发人员应使用标准的laravel授权:
class PostPolicy { public function edit(User $user, Post $post) { return $user->id == $post->owner_id || $user->hasPermissionTo('edit posts'); } }
那么也许最简单的方法不是最好的吗?
看起来很简单:放入软件包,运行完成的迁移并继续。 从长期项目支持的角度来看,这不是最佳选择。
让我们尝试分析通常需要哪些项目? 简单的角色扮演系统。 每个用户几乎总是一个角色。 管理员 好吧,也许是另一个编辑或主持人。 这些角色具有一些权限。 让我们走最直接的方法! 向用户表添加一个新字段!
is_admin或
role 。 然后是
User类的几个助手:
class User { public function isAdmin(): bool {...} public function isEditor(): bool {...} }
现在permishen。 Laravel提供了两种描述它们的基本方法:
Gates和Policy。 我将使用Gates(对于变量中的函数仍然有一个小技巧,但是对于函数式编程爱好者来说,这根本不是一个技巧):
$isAdmin = function (User $user) { return $user->isAdmin(); } $isEditorOrAdmin = function (User $user) { return $user->isAdmin() || $user->isEditor(); } Gate::define('foo-permission', $isAdmin); Gate::define('bar-permission', $isAdmin); Gate::define('editor-permission', $isEditorOrAdmin);
如果项目每个用户需要多个角色,则只需添加
user_roles表并更改
User类的助手。 *信任包的seeder类的内容和此基于代码的授权几乎相同! 但是现在这些规则只是简单地存储在代码中,不需要在数据库中不断地对其进行同步。
我不想说这些软件包是无用的。 这种方法在具有复杂授权系统的项目中非常有用,在该系统中客户自己想在以后配置角色。 也有具有动态权限的项目。 示例:带有子论坛的论坛。 每个子论坛可以有自己的主持人,每个主持人都具有管理员在此子论坛中定义的权限。 另一个例子是电报及其群组。 有同一件事。 这样的项目确实需要一个复杂的,存在所有问题的数据库授权系统。 但是大多数其他人没有。
laravel软件包的情况与Delphi组件的情况类似(老人们记得)。 他们毫不犹豫地放了包装-确实需要或不需要。
因此,我必须在这里的项目中计算$ a + $ b。 是否有任何laravel-sum软件包?
附言:抱歉,我对此许可表示歉意,但我没有找到准确的翻译。