silber / bouncer
Eloquent 角色 和 权限。
Requires
- php: ^8.2|^8.3
- illuminate/auth: ^11.0
- illuminate/cache: ^11.0
- illuminate/container: ^11.0
- illuminate/contracts: ^11.0
- illuminate/database: ^11.0
Requires (Dev)
- illuminate/console: ^11.0
- illuminate/events: ^11.0
- laravel/pint: ^1.14
- orchestra/testbench: ^9.0
- pestphp/pest: 3.x-dev
- phpunit/phpunit: ^11.0
Suggests
- illuminate/console: Allows running the bouncer:clean artisan command
- illuminate/events: Required for multi-tenancy support
- dev-master
- 1.0.x-dev
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-rc.13
- v1.0.0-rc.12
- v1.0.0-rc.11
- v1.0.0-rc.10
- v1.0.0-rc.9
- v1.0.0-rc.8
- v1.0.0-rc.7
- v1.0.0-rc.6
- v1.0.0-rc.5
- v1.0.0-rc.4
- v1.0.0-rc.3
- v1.0.0-rc.2
- v1.0.0-rc.1
- v1.0.0-beta.5
- v1.0.0-beta.4
- v1.0.0-beta.3
- v1.0.0-beta.2
- v1.0.0-beta.1
- v1.0.0-alpha.3
- v1.0.0-alpha.2
- v1.0.0-alpha.1
- 0.1.x-dev
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- 0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- v0.0.26
- v0.0.25
- v0.0.24
- v0.0.23
- v0.0.22
- v0.0.21
- v0.0.20
- v0.0.19
- v0.0.18
- v0.0.17
- v0.0.16
- v0.0.15
- v0.0.14
- v0.0.13
- v0.0.12
- v0.0.11
- v0.0.10
- v0.0.9
- v0.0.8
- v0.0.7
- v0.0.6
- v0.0.5
- v0.0.4
- v0.0.3
- v0.0.2
- v0.0.1
This package is auto-updated.
Last update: 2024-09-17 20:22:51 UTC
README
Bouncer
Bouncer 是一种优雅的、与框架无关的方法,用于管理使用 Eloquent 模型的任何应用程序的角色和权限。
目录
简介
Bouncer 是一种优雅的、与框架无关的方法,用于管理使用 Eloquent 模型的任何应用程序的角色和权限。它具有表达性和流畅的语法,尽可能地不干涉:需要时使用,不需要时忽略。
要快速查看 Bouncer 的功能列表,请查看 速查表。
Bouncer 与您在应用程序中硬编码的其他权限很好地协同工作。您的代码始终优先:如果您的代码允许某个操作,Bouncer 不会干涉。
一旦安装,您只需告诉 Bouncer 您希望在关卡处允许什么
// Give a user the ability to create posts Bouncer::allow($user)->to('create', Post::class); // Alternatively, do it through a role Bouncer::allow('admin')->to('create', Post::class); Bouncer::assign('admin')->to($user); // You can also grant an ability only to a specific model Bouncer::allow($user)->to('edit', $post);
当您在 Laravel 的 gate 中检查权限时,Bouncer 会自动被咨询。如果 Bouncer 看到已授予当前用户的权限(无论是直接授予还是通过角色),它将授权检查。
安装
注意:Bouncer v1.0.2 需要 PHP 8.2+ 和 Laravel/Eloquent 11+。
如果您使用的是 Laravel v6-v10,请使用 Bouncer v1.0.1。如果您使用的是 Laravel v5.5-v5.8,请使用 Bouncer RC6。
在 Laravel 应用中安装 Bouncer
-
使用 composer 安装 Bouncer
composer require silber/bouncer
-
将 Bouncer 的特质添加到您的用户模型中
use Silber\Bouncer\Database\HasRolesAndAbilities; class User extends Model { use HasRolesAndAbilities; }
-
现在,要运行 Bouncer 的迁移。首先,通过运行以下命令将迁移发布到应用程序的
migrations
目录中php artisan vendor:publish --tag="bouncer.migrations"
-
最后,运行迁移
php artisan migrate
外观
每次您在代码中使用 Bouncer
外观时,请记住在文件顶部添加此行到命名空间导入中
use Bouncer;
有关Laravel Facades的更多信息,请参阅Laravel官方文档。
在非 Laravel 应用中安装 Bouncer
-
使用 composer 安装 Bouncer
composer require silber/bouncer
-
使用Eloquent Capsule组件来设置数据库。
use Illuminate\Database\Capsule\Manager as Capsule; $capsule = new Capsule; $capsule->addConnection([/* connection config */]); $capsule->setAsGlobal();
有关更多详细信息,请参阅Eloquent Capsule文档。
-
可以通过以下任一方法运行迁移
-
将 Bouncer 的特质添加到您的用户模型中
use Illuminate\Database\Eloquent\Model; use Silber\Bouncer\Database\HasRolesAndAbilities; class User extends Model { use HasRolesAndAbilities; }
-
创建Bouncer实例
use Silber\Bouncer\Bouncer; $bouncer = Bouncer::create(); // If you are in a request with a current user // that you'd wish to check permissions for, // pass that user to the "create" method: $bouncer = Bouncer::create($user);
如果您在应用程序中使用依赖注入,您可以在容器中将
Bouncer
实例注册为单例。use Silber\Bouncer\Bouncer; use Illuminate\Container\Container; Container::getInstance()->singleton(Bouncer::class, function () { return Bouncer::create(); });
现在您可以向任何需要它的类注入
Bouncer
。create
方法使用合理的默认值创建一个Bouncer
实例。要完全自定义它,请使用make
方法获取工厂实例。通过在工厂上调用create()
来创建Bouncer
实例。use Silber\Bouncer\Bouncer; $bouncer = Bouncer::make() ->withCache($customCacheInstance) ->create();
查看
Factory
类以了解所有可用的自定义选项。 -
设置整个应用程序中使用的用户模型
$bouncer->useUserModel(User::class);
有关更多配置信息,请参阅下方的配置部分。
启用缓存
默认情况下,Bouncer的查询会对当前请求进行缓存。为了获得更好的性能,您可能希望启用跨请求缓存。
使用方法
向用户添加角色和能力变得极其简单。您无需提前创建角色或能力。只需传递角色/能力的名称,Bouncer就会在不存在的情况下创建它们。
注意:以下所有示例都使用了
Bouncer
外观。如果您不使用外观,则可以将Silber\Bouncer\Bouncer
的实例注入到您的类中。
创建角色和权限
让我们创建一个名为admin
的角色,并赋予它从我们网站上ban-users
的能力
Bouncer::allow('admin')->to('ban-users');
就这样。幕后,Bouncer将为您创建一个Role
模型和一个Ability
模型。
如果您想向角色/能力添加额外的属性,例如可读的标题,您可以使用Bouncer
类上的role
和ability
方法手动创建它们。
$admin = Bouncer::role()->firstOrCreate([ 'name' => 'admin', 'title' => 'Administrator', ]); $ban = Bouncer::ability()->firstOrCreate([ 'name' => 'ban-users', 'title' => 'Ban users', ]); Bouncer::allow($admin)->to($ban);
将角色分配给用户
现在,要给用户分配admin
角色,只需告诉bouncer给定的用户应该被分配admin角色即可
Bouncer::assign('admin')->to($user);
或者,您可以直接在用户上调用assign
方法
$user->assign('admin');
直接给用户赋予权限
有时您可能想要直接给用户赋予能力,而不是使用角色
Bouncer::allow($user)->to('ban-users');
同样,您也可以直接从用户处完成同样的操作
$user->allow('ban-users');
将权限限制在模型上
有时您可能想要将能力限制为特定的模型类型。只需将模型名称作为第二个参数传递
Bouncer::allow($user)->to('edit', Post::class);
如果您想将能力限制为特定的模型实例,请传递实际的模型
Bouncer::allow($user)->to('edit', $post);
允许用户或角色“拥有”模型
使用toOwn
方法允许用户管理他们自己的模型
Bouncer::allow($user)->toOwn(Post::class);
现在,当在入口处检查用户是否可以在给定的帖子上进行操作时,帖子的 user_id
将与登录用户的 id
进行比较(这可以自定义)。如果它们匹配,入口将允许进行操作。
上述操作将授予用户对其“拥有”的模型的所有能力。您可以通过调用 to
方法来限制能力。
Bouncer::allow($user)->toOwn(Post::class)->to('view'); // Or pass it an array of abilities: Bouncer::allow($user)->toOwn(Post::class)->to(['view', 'update']);
您还可以允许用户拥有应用程序中所有 类型 的模型。
Bouncer::allow($user)->toOwnEverything(); // And to restrict ownership to a given ability Bouncer::allow($user)->toOwnEverything()->to('view');
从用户撤回角色
bouncer 还可以从用户撤回之前分配的角色。
Bouncer::retract('admin')->from($user);
或者直接在用户上操作。
$user->retract('admin');
删除权限
bouncer 还可以从之前授予用户的权限中移除一个权限。
Bouncer::disallow($user)->to('ban-users');
或者直接在用户上操作。
$user->disallow('ban-users');
注意:如果用户有一个允许他们
ban-users
的角色,他们仍然会拥有这个能力。要禁止它,要么从角色中移除该能力,要么从用户中撤回该角色。
如果能力是通过角色授予的,告诉 bouncer 从角色中移除该能力。
Bouncer::disallow('admin')->to('ban-users');
要移除特定模型类型的能力,请传递其名称作为第二个参数。
Bouncer::disallow($user)->to('delete', Post::class);
警告:如果用户有一个能力可以
delete
特定的$post
实例,上面的代码将 不会 移除该能力。您必须单独移除该能力 - 通过传递实际的$post
作为第二个参数 - 如下所示。
要移除特定模型实例的能力,请传递实际的模型。
Bouncer::disallow($user)->to('delete', $post);
注意:
disallow
方法仅移除之前授予此用户/角色的能力。如果您想禁止更一般能力允许的一小部分,请使用forbid
方法。
禁止权限
Bouncer 还允许您 forbid
一个给定的能力,以便有更精细的控制。有时您可能希望授予用户/角色一个能力,该能力覆盖了广泛的行为,但后来又限制了一小部分行为。
以下是一些示例
-
您可能允许用户查看所有文档,但有一个高度机密的文档他们不应该被允许查看。
Bouncer::allow($user)->to('view', Document::class); Bouncer::forbid($user)->to('view', $classifiedDocument);
-
您可能希望允许您的
superadmin
在您的应用程序中做任何事情,包括添加/删除用户。然后您可能有一个可以执行所有操作,除了管理用户的admin
角色。Bouncer::allow('superadmin')->everything(); Bouncer::allow('admin')->everything(); Bouncer::forbid('admin')->toManage(User::class);
-
您可能希望偶尔封禁用户,移除他们所有能力的权限。但是,实际上移除所有角色和权限意味着当封禁被移除时,我们必须弄清楚他们的原始角色和能力。
使用禁止的能力意味着他们可以保持所有现有的角色和能力,但仍然无权进行任何操作。我们可以通过创建一个特殊的
banned
角色,为该角色禁止所有权限来实现这一点。Bouncer::forbid('banned')->everything();
然后,每次我们想要封禁一个用户时,我们将分配给他们
banned
角色。Bouncer::assign('banned')->to($user);
要取消封禁,我们只需从用户中撤回该角色。
Bouncer::retract('banned')->from($user);
如您所见,Bouncer 的禁止能力为您提供了大量对应用程序权限的精细控制。
取消禁止权限
要移除禁止的能力,请使用 unforbid
方法。
Bouncer::unforbid($user)->to('view', $classifiedDocument);
注意:这将移除任何之前禁止的能力。它 不会 自动允许该能力,如果它不是由授予此用户/角色的不同常规能力允许的话。
检查用户的角色
注意:一般来说,您不需要直接检查角色。更好的做法是允许角色拥有某些能力,然后检查这些能力。如果您需要的功能非常通用,可以创建非常广泛的能力。例如,
access-dashboard
能力始终比直接检查admin
或editor
角色更好。在极少数需要检查角色的场合,该功能在这里提供。
Bouncer 可以检查用户是否具有特定角色
Bouncer::is($user)->a('moderator');
如果您正在检查以元音开头的角色,您可能想使用 an
别名方法
Bouncer::is($user)->an('admin');
对于相反的情况,您也可以检查用户是否 没有 特定角色
Bouncer::is($user)->notA('moderator'); Bouncer::is($user)->notAn('admin');
您可以检查用户是否具有多个角色之一
Bouncer::is($user)->a('moderator', 'editor');
您还可以检查用户是否具有所有给定角色
Bouncer::is($user)->all('editor', 'moderator');
您还可以检查用户是否没有任何给定角色
Bouncer::is($user)->notAn('editor', 'moderator');
这些检查也可以直接在用户上进行
$user->isAn('admin'); $user->isA('subscriber'); $user->isNotAn('admin'); $user->isNotA('subscriber'); $user->isAll('editor', 'moderator');
按角色查询用户
您可以通过用户是否具有特定角色来查询您的用户
$users = User::whereIs('admin')->get();
您还可以传入多个角色,以查询具有 任何 给定角色的用户
$users = User::whereIs('superadmin', 'admin')->get();
要查询具有 所有 给定角色的用户,请使用 whereIsAll
方法
$users = User::whereIsAll('sales', 'marketing')->get();
获取用户的全部角色
您可以直接从用户模型获取用户的所有角色
$roles = $user->getRoles();
获取用户的全部权限
您可以直接从用户模型获取用户的所有能力
$abilities = $user->getAbilities();
这将返回一个用户允许的能力集合,包括通过其角色授予的用户的能力。
您还可以获取一个已明确禁止的能力列表
$forbiddenAbilities = $user->getForbiddenAbilities();
授权用户
用户授权直接在 Laravel 的 Gate
或用户模型 ($user->can($ability)
) 上处理。
为了方便起见,Bouncer
类提供了这些中继方法
Bouncer::can($ability); Bouncer::can($ability, $model); Bouncer::canAny($abilities); Bouncer::canAny($abilities, $model); Bouncer::cannot($ability); Bouncer::cannot($ability, $model); Bouncer::authorize($ability); Bouncer::authorize($ability, $model);
这些方法直接调用其对应的 Gate
类上的方法。
Blade 指令
Bouncer 不添加自己的 blade 指令。由于 Bouncer 直接与 Laravel 的 gate 一起工作,只需使用其 @can
指令来检查当前用户的权限。
@can ('update', $post) <a href="{{ route('post.update', $post) }}">Edit Post</a> @endcan
由于直接检查角色通常 不推荐,Bouncer 不提供单独的指令。如果您仍然坚持检查角色,可以使用通用的 @if
指令。
@if ($user->isAn('admin')) // @endif
刷新缓存
Bouncer 对当前请求执行的查询都进行了缓存。如果您启用 跨请求缓存,缓存将在不同的请求之间持续存在。
在需要时,您可以完全刷新 bouncer 的缓存
Bouncer::refresh();
注意:如果可用,完全刷新所有用户的缓存使用 缓存标签。并非所有缓存驱动程序都支持此功能。请参阅 Laravel 的文档 以查看您的驱动程序是否支持缓存标签。如果您的驱动程序不支持缓存标签,调用
refresh
可能会稍微慢一些,具体取决于系统中用户的数量。
或者,您可以只刷新特定用户的缓存
Bouncer::refreshFor($user);
注意:当使用 多租户作用域 时,这将仅刷新当前作用域上下文中的用户缓存。要清除不同作用域上下文中同一用户的缓存数据,必须在那个作用域内调用它。
多租户
Bouncer 完全支持多租户应用程序,允许您无缝集成同一应用程序内所有租户的 Bouncer 角色和能力。
作用域中间件
要开始使用,首先将 作用域中间件 发布到您的应用程序中
php artisan vendor:publish --tag="bouncer.middleware"
现在,中间件将被发布到 app/Http/Middleware/ScopeBouncer.php
。这个中间件是您告诉 Bouncer 当前请求应使用哪个租户的地方。例如,假设您的所有用户都有一个 account_id
属性,那么您的中间件可能看起来像这样
public function handle($request, Closure $next) { $tenantId = $request->user()->account_id; Bouncer::scope()->to($tenantId); return $next($request); }
当然,您可以修改这个中间件以满足您应用程序的需求,例如从子域等地方拉取租户信息。
现在,中间件已经就位,请确保在您的 HTTP 核心中 注册它
protected $middlewareGroups = [ 'web' => [ // Keep the existing middleware here, and add this: \App\Http\Middleware\ScopeBouncer::class, ] ];
现在,Bouncer 的所有查询都将限定到给定的租户。
自定义 Bouncer 的作用域
根据您应用程序的设置,您可能并不希望 所有 的查询都限定到当前租户。例如,您可能有一组对所有租户都相同的角色/权限,并且只允许用户控制哪些用户被分配哪些角色,以及哪些角色有哪些权限。为了实现这一点,您可以告诉 Bouncer 的作用域只限定 Bouncer 模型的关系,但不限定模型本身
Bouncer::scope()->to($tenantId)->onlyRelations();
此外,您的应用程序可能甚至不允许用户控制特定角色的权限。在这种情况下,告诉 Bouncer 的作用域排除角色权限的作用域,以便这些关系在所有租户中保持全局
Bouncer::scope()->to($tenantId)->onlyRelations()->dontScopeRoleAbilities();
如果您的需求比上面所述更加特殊,您可以使用您需要的任何自定义逻辑创建自己的 Scope
use Silber\Bouncer\Contracts\Scope; class MyScope implements Scope { // Whatever custom logic your app needs }
然后,在一个服务提供者中注册您的自定义作用域
Bouncer::scope(new MyScope);
Bouncer 将在其执行过程中的各个点调用 Scope
接口的方法。您可以根据您特定的需求来处理它们。
配置
Bouncer 默认提供了合理的默认设置,因此大多数情况下不需要任何配置。为了更精细的控制,Bouncer 可以通过调用 Bouncer
类上的各种配置方法来自定义。
如果您只使用这些配置选项中的一两个,可以将它们放入您的 主 AppServiceProvider
的 boot
方法。如果它们开始增长,您可以在 您的 app/Providers
目录 中创建一个单独的 BouncerServiceProvider
类(请记住在 配置数组 providers
中注册它)。
缓存
默认情况下,Bouncer 执行的所有查询都会缓存到当前请求中。为了提高性能,您可能想使用跨请求缓存
Bouncer::cache();
警告:如果您启用跨请求缓存,您将负责在您更改用户的角色/权限时刷新缓存。有关如何刷新缓存的信息,请参阅 刷新缓存。
相反,您有时可能希望 完全禁用 缓存,即使是在同一请求中也是如此
Bouncer::dontCache();
这在单元测试中尤其有用,当您想针对刚刚授予的角色/权限运行断言时。
表
要更改 Bouncer 使用的数据库表名,请传递一个关联数组到 tables
方法。键应该是 Bouncer 的默认表名,值应该是您希望使用的表名。您不需要传递所有表名;只需传递您希望更改的表名即可。
Bouncer::tables([ 'abilities' => 'my_abilities', 'permissions' => 'granted_abilities', ]);
Bouncer 发布的迁移使用此配置中的表名,因此请在实际运行迁移之前确保这些表名已经就位。
自定义模型
您可以轻松扩展 Bouncer 内置的 Role
和 Ability
模型
namespace App\Models; use Silber\Bouncer\Database\Ability as BouncerAbility; class Ability extends BouncerAbility { // custom code }
namespace App\Models; use Silber\Bouncer\Database\Role as BouncerRole; class Role extends BouncerRole { // custom code }
或者,您可以使用Bouncer的IsAbility
和IsRole
特性,而无需扩展Bouncer的任何模型。
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Silber\Bouncer\Database\Concerns\IsAbility; class Ability extends Model { use IsAbility; // custom code }
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Silber\Bouncer\Database\Concerns\IsRole; class Role extends Model { use IsRole; // custom code }
如果您使用特性而不是扩展Bouncer的模型,请务必自行设置正确的$table
名称和$fillable
字段。
无论您使用哪种方法,下一步实际上是要告诉Bouncer使用您的自定义模型。
Bouncer::useAbilityModel(\App\Models\Ability::class); Bouncer::useRoleModel(\App\Models\Role::class);
注意:Eloquent根据父模型名称确定关系的外键(请参阅Eloquent文档)。为了简化,请将自定义类的名称与Bouncer的名称相同:分别命名为
Ability
和Role
。如果您需要使用不同的名称,请确保更新您的迁移文件或覆盖关系方法以显式设置其外键。
用户模型
默认情况下,Bouncer自动使用默认认证守卫的用户模型。
如果您在非默认守卫中使用Bouncer,并且它使用不同的用户模型,您应该让Bouncer知道您想要使用的用户模型。
Bouncer::useUserModel(\App\Admin::class);
所有者
在Bouncer中,所有权概念用于允许用户对“拥有”的模型执行操作。
默认情况下,Bouncer会检查模型的user_id
与当前用户的主键是否匹配。如果需要,可以将此设置为一个不同的属性。
Bouncer::ownedVia('userId');
如果不同的模型使用不同的列来表示所有权,您可以为它们分别注册。
Bouncer::ownedVia(Post::class, 'created_by'); Bouncer::ownedVia(Order::class, 'entered_by');
为了获得更大的控制权,您可以传递一个包含您自定义逻辑的闭包。
Bouncer::ownedVia(Game::class, function ($game, $user) { return $game->team_id == $user->team_id; });
常见问题解答
关于Bouncer,人们经常询问一些概念,所以这里有一些关于这些主题的简要列表。
我在哪里设置应用程序的角色和权限?
可以在常规的Laravel生成器类中生成初始角色和权限。首先为Bouncer创建一个特定的生成器文件。
php artisan make:seeder BouncerSeeder
将所有您的生成角色和权限代码放在生成器的run
方法中。以下是一个示例:
use Bouncer; use Illuminate\Database\Seeder; class BouncerSeeder extends Seeder { public function run() { Bouncer::allow('superadmin')->everything(); Bouncer::allow('admin')->everything(); Bouncer::forbid('admin')->toManage(User::class); Bouncer::allow('editor')->to('create', Post::class); Bouncer::allow('editor')->toOwn(Post::class); // etc. } }
要实际运行它,请将生成器类的名称传递给db:seed
命令的class
选项。
php artisan db:seed --class=BouncerSeeder
我可以为网站的不同部分分别使用不同的角色和权限集吗,例如公共部分和仪表板部分?
Bouncer的scope
可以用来隔离网站的不同部分,为每个部分创建一个具有自己角色和权限的隔离区。
-
创建一个
ScopeBouncer
中间件,该中间件接受一个$identifier
并将其设置为当前作用域。use Bouncer, Closure; class ScopeBouncer { public function handle($request, Closure $next, $identifier) { Bouncer::scope()->to($identifier); return $next($request); } }
-
将此新中间件注册为路由中间件到您的
HTTP Kernel class
。protected $routeMiddleware = [ // Keep the other route middleware, and add this: 'scope-bouncer' => \App\Http\Middleware\ScopeBouncer::class, ];
-
在您的
route service provider
中,分别使用不同的标识符应用此中间件到公共路由和仪表板路由。Route::middleware(['web', 'scope-bouncer:1']) ->namespace($this->namespace) ->group(base_path('routes/public.php')); Route::middleware(['web', 'scope-bouncer:2']) ->namespace($this->namespace) ->group(base_path('routes/dashboard.php'));
就是这样。现在,所有角色和权限都将为您的网站的每个部分单独隔离。要微调作用域的深度,请参阅自定义Bouncer的作用域。
当我尝试运行迁移时,我得到了一个 SQL 错误,指出“指定的键太长”
从Laravel 5.4开始,默认的数据库字符集现在是utf8mb4
。如果您正在使用Laravel 5.4+的某些旧版本数据库(MySQL低于5.7.7或MariaDB低于10.2.2),则在尝试在字符串列上创建索引时将得到SQL错误。要修复此问题,请更改AppServiceProvider
中Laravel的默认字符串长度。
use Illuminate\Support\Facades\Schema; public function boot() { Schema::defaultStringLength(191); }
您可以在这篇Laravel News文章中了解更多信息。
当我尝试运行迁移时,我得到了一个 SQL 错误,指出有“语法错误或访问违规:1064 ... 在 near 'json not null)' 时出错
JSON列是MySQL(5.7.8)和MariaDB(10.2.7)相对较新的功能。如果您使用的是这些数据库的旧版本,则无法使用JSON列。
最佳解决方案是升级您的数据库。如果目前无法升级,您可以将已发布的迁移文件更改为使用text
列。
- $table->json('options')->nullable(); + $table->text('options')->nullable();
控制台命令
bouncer:clean
bouncer:clean
命令会删除未使用的权限。运行此命令将删除两种类型的未使用权限:
-
未分配的权限 - 未分配给任何人的权限。例如
Bouncer::allow($user)->to('view', Plan::class); Bouncer::disallow($user)->to('view', Plan::class);
在此阶段,“查看计划”权限未分配给任何人,因此它将被删除。
注意:根据您应用程序的上下文,您可能不想删除这些权限。如果您允许用户在应用程序的UI中管理权限,您可能不想删除未分配的权限。请参见下文。
-
孤儿权限 - 模型权限,其模型已被删除
Bouncer::allow($user)->to('delete', $plan); $plan->delete();
由于计划不再存在,该权限不再有任何用途,因此它将被删除。
如果您只想删除一种未使用的权限,可以使用以下标志之一运行它:
php artisan bouncer:clean --unassigned
php artisan bouncer:clean --orphaned
如果您不传递任何标志,它将删除两种类型的未使用权限。
要定期自动运行此命令,请将其添加到控制台内核的调度中。
$schedule->command('bouncer:clean')->weekly();
速查表
// Adding abilities for users Bouncer::allow($user)->to('ban-users'); Bouncer::allow($user)->to('edit', Post::class); Bouncer::allow($user)->to('delete', $post); Bouncer::allow($user)->everything(); Bouncer::allow($user)->toManage(Post::class); Bouncer::allow($user)->toManage($post); Bouncer::allow($user)->to('view')->everything(); Bouncer::allow($user)->toOwn(Post::class); Bouncer::allow($user)->toOwnEverything(); // Removing abilities uses the same syntax, e.g. Bouncer::disallow($user)->to('delete', $post); Bouncer::disallow($user)->toManage(Post::class); Bouncer::disallow($user)->toOwn(Post::class); // Adding & removing abilities for roles Bouncer::allow('admin')->to('ban-users'); Bouncer::disallow('admin')->to('ban-users'); // You can also forbid specific abilities with the same syntax... Bouncer::forbid($user)->to('delete', $post); // And also remove a forbidden ability with the same syntax... Bouncer::unforbid($user)->to('delete', $post); // Re-syncing a user's abilities Bouncer::sync($user)->abilities($abilities); // Assigning & retracting roles from users Bouncer::assign('admin')->to($user); Bouncer::retract('admin')->from($user); // Assigning roles to multiple users by ID Bouncer::assign('admin')->to([1, 2, 3]); // Re-syncing a user's roles Bouncer::sync($user)->roles($roles); // Checking the current user's abilities $boolean = Bouncer::can('ban-users'); $boolean = Bouncer::can('edit', Post::class); $boolean = Bouncer::can('delete', $post); $boolean = Bouncer::cannot('ban-users'); $boolean = Bouncer::cannot('edit', Post::class); $boolean = Bouncer::cannot('delete', $post); // Checking a user's roles $boolean = Bouncer::is($user)->a('subscriber'); $boolean = Bouncer::is($user)->an('admin'); $boolean = Bouncer::is($user)->notA('subscriber'); $boolean = Bouncer::is($user)->notAn('admin'); $boolean = Bouncer::is($user)->a('moderator', 'editor'); $boolean = Bouncer::is($user)->all('moderator', 'editor'); Bouncer::cache(); Bouncer::dontCache(); Bouncer::refresh(); Bouncer::refreshFor($user);
此功能中的一些也直接在用户模型上可用
$user->allow('ban-users'); $user->allow('edit', Post::class); $user->allow('delete', $post); $user->disallow('ban-users'); $user->disallow('edit', Post::class); $user->disallow('delete', $post); $user->assign('admin'); $user->retract('admin'); $boolean = $user->isAn('admin'); $boolean = $user->isAn('editor', 'moderator'); $boolean = $user->isAll('moderator', 'editor'); $boolean = $user->isNotAn('admin', 'moderator'); // Querying users by their roles $users = User::whereIs('superadmin')->get(); $users = User::whereIs('superadmin', 'admin')->get(); $users = User::whereIsAll('sales', 'marketing')->get(); $abilities = $user->getAbilities(); $forbidden = $user->getForbiddenAbilities();
替代方案
在Spatie慷慨赐予社区的无数个包中,您会发现出色的laravel-permission包。和Bouncer一样,它很好地集成了Laravel内置的gate和权限检查,但在语法、数据库结构和功能方面有一套不同的设计选择。
许可证
Bouncer是开源软件,许可协议为MIT许可。