natansdj/bouncer

优雅的角色和权限。

维护者

详细信息

github.com/natansdj/bouncer

源代码


README

Bouncer

Build Status Total Downloads License

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 需要 PHP 7.2+ 和 Laravel/Eloquent 6.0+

如果您尚未更新,请使用 Bouncer RC6。它支持所有回溯到 PHP 5.5 & Laravel 5.1,且没有已知的错误。

在 Laravel 应用程序中安装 Bouncer

  1. 使用 composer 安装 Bouncer
$ composer require silber/bouncer v1.0.0-rc.8
  1. 将 Bouncer 特性添加到您的用户模型中

    use Silber\Bouncer\Database\HasRolesAndAbilities;
    
    class User extends Model
    {
        use HasRolesAndAbilities;
    }
  2. 现在,要运行 Bouncer 的迁移,首先通过运行以下命令将迁移发布到您的应用程序的 migrations 目录

    php artisan vendor:publish --tag="bouncer.migrations"
    
  3. 最后,运行迁移

    php artisan migrate
    

门面

每次您在代码中使用 Bouncer 门面时,请记住在文件顶部添加此行到您的命名空间导入

use Bouncer;

有关 Laravel Facades 的更多信息,请参阅 Laravel 文档

在非 Laravel 应用程序中安装 Bouncer

  1. 使用 composer 安装 Bouncer

    $ composer require silber/bouncer v1.0.0-rc.8
    
  2. 使用Eloquent Capsule组件设置数据库。

    use Illuminate\Database\Capsule\Manager as Capsule;
    
    $capsule = new Capsule;
    
    $capsule->addConnection([/* connection config */]);
    
    $capsule->setAsGlobal();

    有关更多详细信息,请参阅Eloquent Capsule文档

  3. 可以通过以下任一方法运行迁移

    • 使用vagabond等工具在Laravel应用程序外部运行Laravel迁移。必要的迁移可以在迁移占位符文件中找到。

    • 或者,您可以直接在数据库中运行原始SQL

  4. 将 Bouncer 特性添加到您的用户模型中

    use Illuminate\Database\Eloquent\Model;
    use Silber\Bouncer\Database\HasRolesAndAbilities;
    
    class User extends Model
    {
        use HasRolesAndAbilities;
    }
  5. 创建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以查看所有可用的自定义选项。

  6. 设置在整个应用程序中使用哪个模型作为用户模型

    $bouncer->useUserModel(User::class);

    有关其他配置,请参阅下面的配置部分

启用缓存

默认情况下,Bouncer的查询在当前请求中缓存。为了获得更好的性能,您可能希望启用跨请求缓存

用法

将角色和能力添加到用户中非常容易。您无需提前创建角色或能力。只需传递角色/能力的名称,如果不存在,Bouncer将创建它。

注意:以下所有示例都使用Bouncer外观。如果您不使用外观,则可以将Silber\Bouncer\Bouncer实例注入到您的类中。

创建角色和权限

让我们创建一个名为admin的角色,并给它赋予从我们网站上ban-users的能力

Bouncer::allow('admin')->to('ban-users');

就这样。幕后,Bouncer将为您创建一个Role模型和一个Ability模型。

如果您想向角色/能力添加额外的属性,例如人类可读的标题,您可以使用Bouncer类上的roleability方法手动创建它们。

$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该用户应分配管理员角色

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);

警告:如果用户有删除特定 $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 能力总是比直接检查 admineditor 角色更好。如果您确实需要偶尔检查角色,这里提供了该功能。

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。

如果您只使用其中一个或两个配置选项,可以将它们放入主AppServiceProviderboot方法中。如果它们开始增长,您可以在app/Providers目录中创建一个单独的BouncerServiceProvider类(请记住在providers配置数组中注册它)。

缓存

默认情况下,Bouncer将缓存当前请求中执行的查询。为了提高性能,您可能希望使用跨请求缓存。

Bouncer::cache();

注意:如果您启用跨请求缓存,您负责在修改用户角色/能力时刷新缓存。有关刷新缓存的说明,请参阅刷新缓存

相反,您有时可能希望即使在同一请求中,也完全禁用缓存

Bouncer::dontCache();

这在单元测试中特别有用,当您想对刚刚赋予的角色/能力运行断言时。

要更改Bouncer使用的数据库表名,请向tables方法传递一个关联数组。键应该是Bouncer的默认表名,值应该是您希望使用的表名。您不需要传递所有表名,只需传递您希望更改的即可。

Bouncer::tables([
    'abilities' => 'my_abilities',
    'permissions' => 'granted_abilities',
]);

Bouncer的发布迁移使用此配置中的表名,因此在实际运行迁移文件之前,请确保它们已就绪。

自定义模型

您可以轻松扩展Bouncer内置的RoleAbility模型

use Silber\Bouncer\Database\Ability;

class MyAbility extends Ability
{
    // custom code
}
use Silber\Bouncer\Database\Role;

class MyRole extends Role
{
    // custom code
}

或者,您可以使用Bouncer的IsAbilityIsRole特性,而不需要扩展Bouncer的任何模型

use Illuminate\Database\Eloquent\Model;
use Silber\Bouncer\Database\Concerns\IsAbility;

class MyAbility extends Model
{
    use IsAbility;

    // custom code
}
use Illuminate\Database\Eloquent\Model;
use Silber\Bouncer\Database\Concerns\IsRole;

class MyRole extends Model
{
    use IsRole;

    // custom code
}

如果您使用特性而不是扩展Bouncer的模型,请确保自己设置正确的$table名称和$fillable字段。

无论您使用哪种方法,下一步是实际上告诉Bouncer使用您的自定义模型

Bouncer::useAbilityModel(MyAbility::class);
Bouncer::useRoleModel(MyRole::class);

用户模型

默认情况下,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可以用来分隔网站的不同部分,为每个部分创建一个拥有自己角色和功能的独立区域

  1. 创建一个ScopeBouncer 中间件,它接受一个$identifier并将其设置为当前作用域

    use Bouncer, Closure;
    
    class ScopeBouncer
    {
        public function handle($request, Closure $next, $identifier)
        {
            Bouncer::scope()->to($identifier);
    
            return $next($request);
        }
    }
  2. 将这个新中间件注册为你的HTTP 核心类中的路由中间件

    protected $routeMiddleware = [
        // Keep the other route middleware, and add this:
        'scope-bouncer' => \App\Http\Middleware\ScopeBouncer::class,
    ];
  3. 在你的路由服务提供者中,分别使用不同的标识符应用此中间件以处理公开路由和仪表板路由

    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。如果你正在使用某些数据库的较旧版本(MySQL低于5.7.7或MariaDB低于10.2.2),在尝试在字符串列上创建索引时,你会得到一个SQL错误。为了解决这个问题,请在你的AppServiceProvider中更改Laravel的默认字符串长度

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

你可以在这篇Laravel新闻文章中了解更多信息。

我尝试运行迁移,但遇到“语法错误或访问违规:1064 ... 使用 near json not null)”的 SQL 错误。

JSON列是MySQL(5.7.8)和MariaDB(10.0.1)的一个相对较新的功能。如果你正在使用这些数据库的较旧版本,则不能使用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);

    此时,“查看计划”功能尚未分配给任何人,因此它将被删除。

    注意:根据你应用程序的上下文,你可能不想删除这些功能。如果你允许用户通过应用程序的用户界面管理功能,你可能想删除未分配的功能。请参阅以下内容。

  • 孤儿功能 - 模型功能,其模型已被删除

    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慷慨赠予社区的成千上万个软件包中,你可以找到优秀的Spatie软件包,即laravel-permission。就像Bouncer一样,它很好地与Laravel内置的权限和权限检查集成,但在语法、数据库结构和功能方面有不同的一套设计选择。

许可协议

Bouncer是一个开源软件,采用MIT许可证