laravel-permission 发布版本: 2.11.0

将用户与权限和角色关联

赞助

If you want to quickly add authentication and authorization to Laravel projects, feel free to check Auth0's Laravel SDK and free plan at https://auth0.com/overview.

Packagist上的最新版本 Build Status ![StyleCI(https://styleci.io/repos/42480275/shield)(https://styleci.io/repos/42480275) [!总下载

一旦安装,你可以做这样的事情:

// Adding permissions to a user
$user->givePermissionTo('edit articles');

// Adding permissions via a role
$user->assignRole('writer');

$role->givePermissionTo('edit articles');

如果你使用多个警卫,我们也会覆盖你。每个守卫都有自己的一套权限和角色,可以分配给守卫的用户。请阅读自述文件中的使用多重守卫部分。

由于所有权限都将在Laravel的门户上注册,因此您可以使用Laravel的默认“can”功能测试用户是否具有权限:

$user->can('edit articles');

Spatie是比利时安特卫普的一家网页设计机构。你会发现所有的概述 我们的开源项目在我们的网站上

安装

Laravel

该软件包可用于Laravel 5.4或更高版本。如果您使用的是旧版本的Laravel,请查看该软件包的v1分支

您可以通过作曲家安装软件包:

composer require spatie/laravel-permission

在Laravel 5.5中,服务提供商将自动获得注册。在旧版本的框架中,只需在config / app.php文件中添加服务提供者即可:

'providers' => [
    // ...
    Spatie\Permission\PermissionServiceProvider::class,
];

您可以发布迁移

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"

如果你为你的User模型使用UUID或GUID,你可以更新create_permission_tables.php迁移并用下面的代码替换$ table-> morphs('model')

$table->uuid('model_id');
$table->string('model_type');

迁移发布后,您可以通过运行迁移来创建角色和权限表:

php artisan migrate

你可以发布配置文件:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"

发布时,config / permission.php`配置文件包含:

return [

    'models' => [

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your permissions. Of course, it
         * is often just the "Permission" model but you may use whatever you like.
         *
         * The model you want to use as a Permission model needs to implement the
         * `Spatie\Permission\Contracts\Permission` contract.
         */

        'permission' => Spatie\Permission\Models\Permission::class,

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * Eloquent model should be used to retrieve your roles. Of course, it
         * is often just the "Role" model but you may use whatever you like.
         *
         * The model you want to use as a Role model needs to implement the
         * `Spatie\Permission\Contracts\Role` contract.
         */

        'role' => Spatie\Permission\Models\Role::class,

    ],

    'table_names' => [

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'roles' => 'roles',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your permissions. We have chosen a basic
         * default value but you may easily change it to any table you like.
         */

        'permissions' => 'permissions',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your models permissions. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'model_has_permissions' => 'model_has_permissions',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your models roles. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'model_has_roles' => 'model_has_roles',

        /*
         * When using the "HasRoles" trait from this package, we need to know which
         * table should be used to retrieve your roles permissions. We have chosen a
         * basic default value but you may easily change it to any table you like.
         */

        'role_has_permissions' => 'role_has_permissions',
    ],

    /*
     * By default all permissions will be cached for 24 hours unless a permission or
     * role is updated. Then the cache will be flushed immediately.
     */

    'cache_expiration_time' => 60 * 24,

    /*
     * When set to true, the required permission/role names are added to the exception
     * message. This could be considered an information leak in some contexts, so
     * the default setting is false here for optimum safety.
     */

    'display_permission_in_exception' => false,
];

流明

您可以通过Composer安装软件包:

composer require spatie/laravel-permission

复制所需的文件:

cp vendor/spatie/laravel-permission/config/permission.php config/permission.php
cp vendor/spatie/laravel-permission/database/migrations/create_permission_tables.php.stub database/migrations/2018_01_01_000000_create_permission_tables.php

您还需要在config / auth.php创建另一个配置文件。在Laravel存储库中获取它,或者运行以下命令:

curl -Ls https://raw.githubusercontent.com/laravel/lumen-framework/5.5/config/auth.php -o config/auth.php

现在,运行你的迁移:

php artisan migrate

然后,在bootstrap / app.php中注册中间件:

$app->routeMiddleware([
    'auth'       => App\Http\Middleware\Authenticate::class,
    'permission' => Spatie\Permission\Middlewares\PermissionMiddleware::class,
    'role'       => Spatie\Permission\Middlewares\RoleMiddleware::class,
]);

以及配置和服务提供者:

$app->configure('permission');
$app->register(Spatie\Permission\PermissionServiceProvider::class);

用法

首先,将Spatie \ Permission \ Traits \ HasRoles特征添加到您的User模型中:

use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // ...
}

未定义 *注意,如果你需要在另一个模型ex.Page中使用HasRoles特性,你还需要添加protected $ guard_name ='web';`以及那个模型,否则你会得到一个错误 ```php use Illuminate\Database\Eloquent\Model; use Spatie\Permission\Traits\HasRoles;

class Page extends Model { use HasRoles;

protected $guard_name = 'web'; // or whatever guard you want to use

// ... }


该软件包允许用户与权限和角色关联。每个角色都与多个权限关联。
“角色”和“权限”是常规的雄辩模型。他们需要一个`name`并且可以像这样创建:
```php
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;

$role = Role::create(['name' => 'writer']);
$permission = Permission::create(['name' => 'edit articles']);

可以使用以下方法中的一种将权限分配给角色:

$role->givePermissionTo($permission);
$permission->assignRole($role);

可以使用以下方法之一将多个权限同步到一个角色:

$role->syncPermissions($permissions);
$permission->syncRoles($roles);

使用以下方法之一可以从角色中删除权限:

$role->revokePermissionTo($permission);
$permission->removeRole($role);

如果你使用多个警卫,那么guard_name属性也需要设置。请阅读自述文件中的使用多重守卫部分。

“HasRoles”特征为您的模型添加了Eloquent关系,这些关系可以直接访问或用作基本查询:

// get a list of all permissions directly assigned to the user
$permissions = $user->permissions;

// get all permissions inherited by the user via roles
$permissions = $user->getAllPermissions();

// get a collection of all defined roles
$roles = $user->getRoleNames(); // Returns a collection

HasRoles特征还为您的模型添加了一个“角色”范围,以便将查询范围限定为某些角色或权限:

$users = User::role('writer')->get(); // Returns only users with the role 'writer'

角色范围可以接受一个字符串,一个Spatie \ Permission \ Models \ Role对象或一个\ Illuminate \ Support \ Collection对象。

同样的特质也增加了一个范围,只让用户拥有一定的权限。

$users = User::permission('edit articles')->get(); // Returns only users with the permission 'edit articles' (inherited or directly)

该作用域可以接受一个字符串,一个Spatie \ Permission \ Models \ Permission对象或\ Illuminate \ Support \ Collection对象。

使用“直接”权限(请参阅下面的内容以使用角色和权限)

可以授予任何用户权限:

$user->givePermissionTo('edit articles');

// You can also give multiple permission at once
$user->givePermissionTo('edit articles', 'delete articles');

// You may also pass an array
$user->givePermissionTo(['edit articles', 'delete articles']);

用户可以撤销权限:

$user->revokePermissionTo('edit articles');

或者一次性撤消并添加新的权限:

$user->syncPermissions(['edit articles', 'delete articles']);

您可以测试用户是否拥有权限:

$user->hasPermissionTo('edit articles');

或者你可以传递一个代表权限ID的整数

$user->hasPermissionTo('1');
$user->hasPermissionTo(Permission::find(1)->id);
$user->hasPermissionTo($somePermission->id);

...或者如果用户有多个权限:

$user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']);

您也可以传递整数以通过权限ID进行查找

$user->hasAnyPermission(['edit articles', 1, 5]);

已保存的权限将在默认警卫的Illuminate \ Auth \ Access \ Gate类中注册。所以你可以 测试用户是否拥有Laravel默认的can功能的权限:

$user->can('edit articles');

通过角色使用权限

角色可以分配给任何用户:

$user->assignRole('writer');

// You can also assign multiple roles at once
$user->assignRole('writer', 'admin');
// or as an array
$user->assignRole(['writer', 'admin']);

角色可以从用户中删除:

$user->removeRole('writer');

角色也可以同步:

// All current roles will be removed from the user and replaced by the array given
$user->syncRoles(['writer', 'admin']);

您可以确定用户是否具有某个角色:

$user->hasRole('writer');

您还可以确定用户是否具有任何给定的角色列表:

$user->hasAnyRole(Role::all());

您还可以确定用户是否具有所有给定的角色列表:

$user->hasAllRoles(Role::all());

assignRolehasRolehasAnyRolehasAllRolesremoveRole函数可以接受 字符串,Spatie \ Permission \ Models \ Role对象或\ Illuminate \ Support \ Collection对象。

可以给角色一个许可:

$role->givePermissionTo('edit articles');

您可以确定角色是否具有某种权限:

$role->hasPermissionTo('edit articles');

可以从角色撤销权限:

$role->revokePermissionTo('edit articles');

givePermissionTorevokePermissionTo函数可以接受一个 字符串或Spatie \ Permission \ Models \ Permission对象。

权限是从角色自动继承的。 另外,个人权限也可以分配给用户。 例如:

$role = Role::findByName('writer');
$role->givePermissionTo('edit articles');

$user->assignRole('writer');

$user->givePermissionTo('delete articles');

在上面的例子中,角色被授予编辑文章的权限,并且该角色被分配给用户。 现在,用户可以编辑文章并删除文章。 '删除文章'的权限是用户的直接许可,因为它直接分配给他们。 当我们调用$ user-> hasDirectPermission('delete articles')它返回'true时, 但对$ user-> hasDirectPermission('编辑文章')为`false'。

如果您为应用程序中的角色和用户构建权限并希望限制或更改用户角色的继承权限(即仅允许更改用户的直接权限),则此方法非常有用。

您可以列出所有这些权限:

// Direct permissions
$user->getDirectPermissions() // Or $user->permissions;

// Permissions inherited from the user's roles
$user->getPermissionsViaRoles();

// All permissions which apply on the user (inherited and direct)
$user->getAllPermissions();

所有这些响应都是Spatie \ Permission \ Models \ Permission对象的集合。

如果我们按照前面的例子,第一个响应将是一个具有delete article权限的集合 第二个将是一个带有“编辑文章”权限的集合,第三个将包含两者。

使用Blade指令

该软件包还添加了Blade指令来验证当前登录的用户是否具有全部或任何给定的角色列表。

或者你可以传入guard作为第二个参数来执行检查。

刀片和角色

测试一个特定的角色:

@role('writer')
    I am a writer!
@else
    I am not a writer...
@endrole

是相同的

@hasrole('writer')
    I am a writer!
@else
    I am not a writer...
@endhasrole

测试列表中的任何角色:

@hasanyrole($collectionOfRoles)
    I have one or more of these roles!
@else
    I have none of these roles...
@endhasanyrole
// or
@hasanyrole('writer|admin')
    I am either a writer or an admin or both!
@else
    I have none of these roles...
@endhasanyrole

测试所有角色:

@hasallroles($collectionOfRoles)
    I have all of these roles!
@else
    I do not have all of these roles...
@endhasallroles
// or
@hasallroles('writer|admin')
    I am both a writer and an admin!
@else
    I do not have all of these roles...
@endhasallroles

刀片和权限

该软件包不会添加任何特定于权限的Blade指令。相反,使用Laravel的原生@ can指令来检查用户是否具有某种权限。

@can('edit articles')
  //
@endcan

要么

@if(auth()->user()->can('edit articles') && $some_other_condition)
  //
@endif

使用多个警卫

当使用默认的Laravel身份验证配置时,所有上述方法都可以使用,无需额外的配置。

但是,使用多个警卫时,他们将充当您的权限和角色的命名空间。每个守卫都有自己的一套权限和角色,可以分配给他们的用户模型。

对多个警卫使用权限和角色

默认情况下,默认防护(config('auth.defaults.guard'))将用作新权限和角色的保护。在为特定警卫创建权限和角色时,您必须在模型上指定他们的guard_name

// Create a superadmin role for the admin users
$role = Role::create(['guard_name' => 'admin', 'name' => 'superadmin']);

// Define a `publish articles` permission for the admin users belonging to the admin guard
$permission = Permission::create(['guard_name' => 'admin', 'name' => 'publish articles']);

// Define a *different* `publish articles` permission for the regular users belonging to the web guard
$permission = Permission::create(['guard_name' => 'web', 'name' => 'publish articles']);

要检查用户是否具有特定后卫的权限:

$user->hasPermissionTo('publish articles', 'admin');

分配权限和角色来保护用户

您可以使用相同的方法为用户分配权限和角色,如通过角色使用权限中所述。只要确保权限或角色上的guard_name与用户的守卫相匹配,否则会抛出GuardDoesNotMatch异常。

使用带多个警卫的刀片指令

您可以使用使用刀片指令中列出的所有刀片指令,方法是传入您希望用作该指令第二个参数的警卫:

@role('super-admin', 'admin')
    I am a super-admin!
@else
    I am not a super-admin...
@endrole

使用中间件

该软件包附带RoleMiddlewarePermissionMiddleware中间件。你可以将它们添加到你的app / Http / Kernel.php文件中。

protected $routeMiddleware = [
    // ...
    'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
    'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
];

然后,您可以使用中间件规则保护您的路线:

Route::group(['middleware' => ['role:super-admin']], function () {
    //
});

Route::group(['middleware' => ['permission:publish articles']], function () {
    //
});

Route::group(['middleware' => ['role:super-admin','permission:publish articles']], function () {
    //
});

或者,您可以用|(管道)字符分隔多个角色或权限:

Route::group(['middleware' => ['role:super-admin|writer']], function () {
    //
});

Route::group(['middleware' => ['permission:publish articles|edit articles']], function () {
    //
});

通过在构造函数中设置所需的中间件,可以同样保护您的控制器:

public function __construct()
{
    $this->middleware(['role:super-admin','permission:publish articles|edit articles']);
}

捕获角色和权限失败

如果你想覆盖默认的403响应,你可以使用你的应用程序的异常处理程序捕获UnauthorizedException

public function render($request, Exception $exception)
{
    if ($exception instanceof \Spatie\Permission\Exceptions\UnauthorizedException) {
        // Code here ...
    }

    return parent::render($request, $exception);
}

使用手工命令

您可以使用artisan命令从控制台创建角色或权限。

php artisan permission:create-role writer
php artisan permission:create-permission "edit articles"

在为特定警卫创建权限和角色时,可以将警卫名称指定为第二个参数:

php artisan permission:create-role writer web
php artisan permission:create-permission "edit articles" web

单元测试

在你的应用程序的测试中,如果你没有将角色和权限作为你的测试setUp()的一部分进行播种,那么你可能会遇到鸡/蛋的情况,其中角色和权限没有在门上注册(因为你的测试创建了它们之后门登记完成)。解决这个问题很简单:在你的测试中,只需添加一个setUp()指令来重新注册权限,如下所示:

    public function setUp()
    {
        // first include all the normal setUp operations
        parent::setUp();

        // now re-register all the roles and permissions
        $this->app->make(\Spatie\Permission\PermissionRegistrar::class)->registerPermissions();
    }

数据库播种

有关数据库种子的两个注意事项

1.最好在播种之前刷新spatie.permission.cache,以避免缓存冲突错误。这可以通过Artisan命令(稍后参见故障排除:缓存部分)或直接在播种机类中完成(参见下面的示例)。 2.下面是一个示例播种器,它清除缓存,创建权限,然后为角色分配权限:

 use Illuminate\Database\Seeder;
 use Spatie\Permission\Models\Role;
 use Spatie\Permission\Models\Permission;

 class RolesAndPermissionsSeeder extends Seeder
 {
     public function run()
     {
         // Reset cached roles and permissions
         app()['cache']->forget('spatie.permission.cache');

         // create permissions
         Permission::create(['name' => 'edit articles']);
         Permission::create(['name' => 'delete articles']);
         Permission::create(['name' => 'publish articles']);
         Permission::create(['name' => 'unpublish articles']);

         // create roles and assign created permissions

         $role = Role::create(['name' => 'writer']);
         $role->givePermissionTo('edit articles');

         $role = Role::create(['name' => 'moderator']);
         $role->givePermissionTo(['publish articles', 'unpublish articles']);

         $role = Role::create(['name' => 'super-admin']);
         $role->givePermissionTo(Permission::all());
     }
 }

扩展

如果您需要扩展现有的“角色”或“权限”模型,请注意:

您的角色模型需要扩展Spatie \ Permission \ Models \ Role模型 您的Permission模型需要扩展Spatie \ Permission \ Models \ Permission模型 如果您需要替换现有的RolePermission模型,您需要保留这些模型 记住以下事项:

您的角色模型需要实施Spatie \ Permission \ Contracts \ Role合同 您的Permission模式需要执行Spatie \ Permission \ Contracts \ Permission合同 在这两种情况下,无论是扩展还是替换,您都需要在配置中指定新模型。为此,您必须在使用此命令发布配置后更新配置文件中的models.rolemodels.permission值:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"

高速缓存

缓存角色和权限数据以加速性能。

当您使用提供的方法来操作角色和权限时,缓存会自动为您重置:

$user->assignRole('writer');
$user->removeRole('writer');
$user->syncRoles(params);
$role->givePermissionTo('edit articles');
$role->revokePermissionTo('edit articles');
$role->syncPermissions(params);
$permission->assignRole('writer');
$permission->removeRole('writer');
$permission->syncRoles(params);

但是,如果直接在数据库中操作权限/角色数据而不是调用提供的方法,则除非手动重置缓存,否则不会看到应用程序中反映的更改。

手动缓存重置

要手动重置此软件包的缓存,请运行:

php artisan cache:forget spatie.permission.cache

缓存标识符

提示:如果您正在利用缓存服务,如redismemcached,并且还有其他网站 在您的服务器上运行,您可能会遇到缓存冲突。设置自己的缓存“前缀”是谨慎的 在/ config / cache.php中为每个应用程序独有的东西。这将阻止其他应用程序 从意外使用/更改您的缓存数据。

需要用户界面?

该软件包没有随附任何屏幕,您应该自行构建。要开始Caleb Oki

测试

composer test

更新日志

请参阅CHANGELOG以获取最近更改的更多信息。

特约

详细信息请参阅CONTRIBUTING

安全

如果您发现任何与安全相关的问题,请发送电子邮件至freek@spatie.be,而不是使用问题跟踪器。

明信片软件

你可以自由使用这个软件包,但是如果它使用到你的生产环境中,我们非常感谢你给我们发送你家乡的明信片,并提及我们使用的是哪些软件包。

我们的地址是:Spatie,Samberstraat 69D,2060安特卫普,比利时。

我们发布所有收到的明信片在我们公司网站上

积分

特别感谢Alex Vanderbistv2的大力帮助,以及对Chris Brown的长期支持,帮助我们维护包裹。

资源

备择方案

Povilas Korop在[在Laravel News的文章中]列出了各种替代方案[https://laravel-news.com/two-best-roles-permissions-包)。在同一篇文章中,他将laravel-permission与[Joseph Silber](https://github.com/JosephSilber)的[Bouncer]((https://github.com/JosephSilber/bouncer))进行了比较,在我们的书也是一个很好的包。

支持我们

Spatie是位于比利时安特卫普的网页设计机构。您可以在我们的网站上找到我们所有开源项目的概述(https://spatie.be/opensource)。

你的业务取决于我们的贡献吗?在Patreon上伸出援助之手。 所有承诺将致力于分配维护和新的真棒材料的劳动力。

执照

MIT许可证(MIT)。请参阅许可证文件了解更多信息。