isakzhanov-r/laravel-permissions

用于在 Laravel 项目中使用用户角色和权限的软件包

v1.0.5 2021-02-03 14:02 UTC

This package is auto-updated.

Last update: 2024-09-29 06:02:44 UTC


README

基本角色和权限是一个简洁灵活的方法,用于添加基于角色的权限

Total Downloads Latest Stable Version Latest Unstable Version License

内容

安装

要获取 Laravel Permissions 软件包的最新版本,只需使用 Composer 添加项目

$ composer require isakzhanov-r/laravel-permissions

当然,如果您想手动更新 composer.json 中的依赖项 require 块并运行 composer update,也可以这样做

{
    "require-dev": {
        "isakzhanov-r/laravel-permissions": "^1.0"
    }
}

如果不使用自动发现,请将 ServiceProvider 添加到 config/app.php 中的 providers 数组

IsakzhanovR\Permissions\ServiceProvider::class;

使用发布命令将包配置复制到本地配置

php artisan vendor:publish --provider="IsakzhanovR\Permissions\ServiceProvider"

您可以通过运行迁移来创建数据库表

php artisan migrate

此命令将创建这样的 rolespermissionsuser_rolespermissible 表。

但您也可以使用此命令进行自动安装

php artisan laravel-permissions:migrate

此命令将发布配置文件。运行迁移命令、生成表模型,并更改用户模型。包的所有配置都将自动进行。执行此命令后,您无需进行任何配置。

Role.php
Permission.php
Permissible.php

配置

要进一步自定义表名和模型命名空间,请在运行 php artisan migrate 命令后编辑 config/laravel_permissions.php

php artisan vendor:publish --provider="IsakzhanovR\Permissions\ServiceProvider

在运行 php artisan migrate 命令之前,将出现四个新表

    • users - 与用户关联的默认表
    • roles - 存储角色记录
    • permissions - 存储权限记录
    • user_roles - 存储角色和用户之间的多对多关系
    • permissible - 存储其他实体(用户、角色等)与权限之间的多对多关系
  • foreign_key - 表中的外键关系

  • models - 模型类的引用

模型

角色模型

  • 创建一个角色模型,使用以下示例
namespace App\Models;

use IsakzhanovR\Permissions\Models\Role as LaravelRole;

final class Role extends LaravelRole
{
        protected $fillable = [
            'title',
            'slug',
            'description',
        ];
}
  • 创建模型后,将模型引用设置在文件 config/laravel_permissions
return [
//...
'models' => [
    //....
    'role' => App\Models\Role::class, // or use string 'App\\Models\\Role'
    //....
    ],
];
  • 或者使用命令 php artisan laravel-permissions:migrate 自动生成

Role 模型有三个主要属性

  • slug — 角色的唯一名称,用于在应用程序层中查找角色信息。例如:“admin”、“owner”、“manager”。
  • title — 角色的人类可读名称。不一定唯一,是可选的。例如:“用户管理员”、“项目所有者”、“项目经理”。
  • description — 角色功能的更详细说明。也是可选的;其字段在数据库中是可空的。

基本模型 IsakzhanovR\Permissions\Models\Role 使用特质 HasPermissions

权限模型

  • 使用以下示例创建权限模型
namespace App\Models;

use IsakzhanovR\Permissions\Models\Permission as LaravelPermission;

final class Permission extends LaravelPermission
{
        protected $fillable = [
            'title',
            'slug',
            'description',
        ];
}
  • 创建模型后,将模型引用设置在文件 config/laravel_permissions
return [
//...
'models' => [
    //....
    'permission' => App\Models\Permission::class,
    //....
    ],
//....
];
  • 或者使用命令 php artisan laravel-permissions:migrate 自动生成

Permission 模型与角色具有相同的三个属性

  • slug — 权限的唯一名称,用于在应用层中查找角色信息。例如:"create-user","update-user","delete-user"。
  • title — 权限的易读名称。不一定是唯一的,是可选的。例如:"创建用户","更新用户","删除用户"。
  • description — 对权限所做操作的更详细说明。

查看默认模型 IsakzhanovR\Permissions\Models\Permission,您将看到用户和角色之间的 morphedByMany 关系。您可以扩展此列表以包含自己的实体。

示例

final class Permission extends LaravelPermission
{
    ....
    public function posts()
    {
        return $this->morphedByMany(PostType::class, 'permissible', 'permissible');
    }
    ....
}

PostType 模型必须使用特性 HasPermissions

可授权模型

这是标准的多态枢轴模型。Permissible 模型具有相同的三个属性

  • permission_id — 权限的外键。
  • permissible_type — 属于模型(类名)。
  • permissible_id — 属于模型(键)。

您还需要创建一个名为 Permissible 的模型,并从 IsakzhanovR\Permissions\Models\Permissible 继承。

use IsakzhanovR\Permissions\Models\Permissible as LaravelPermissible;

final class Permissible extends LaravelPermissible
{

}

创建模型后,您还需要在配置文件中添加链接

return [
//...
    'models' => [
        //....
        "permissible" => App\Models\Permissible::class,
        //....
    ],
];

或使用命令自动安装包并生成模型和配置文件

用法

创建

让我们先创建以下 RolesPermissions

    use \App\Models\Role;
    $admin = new Role();
    $admin->slug  = 'admin';
    $admin->title = 'Administrator';
    $admin->description  = 'User is the administrator of a project'; // optional
    $admin->save();

    $manager = new Role();
    $manager->title = 'Project Manager';
    // if you do not specify 'slug' from title 'project-manager' by the method setSlugAttribute()
    $manager->description  = 'User is the manager of a given project'; // optional
    $manager->save();

现在我们只需要创建权限:我们将创建不带描述的权限,而 slug 是从标题中创建的

    use \App\Models\Permission;
    $createPost = new Permission();
    $createPost->title = 'Create Post'; // slug = create-post
    $createPost->save();

    $createNews = new Permission();
    $createNews->title = 'Create News'; // slug = create-news
    $createNews->save();

    $updatePost = new Permission();
    $updatePost->title = 'Update Post'; // slug = update-post
    $updatePost->save();

    $updateNews = new Permission();
    $updateNews->title = 'Update News'; // slug = update-news
    $updateNews->save();

    $updateProfile = new Permission();
    $updateProfile->title = 'Update Profile'; // slug = update-profile
    $updateProfile->save();

    $deletePost = new Permission();
    $deletePost->title = 'Delete Post'; // slug = delete-post
    $deletePost->save();

    $deleteNews = new Permission();
    $deleteNews->title = 'Delete News'; // slug = delete-news
    $deleteNews->save();

用户模型

首先,将 IsakzhanovR\Permissions\Traits\HasPermissionsIsakzhanovR\Permissions\Traits\HasRoles 特性添加到您的 User 模型中。

如果您使用命令 php artisan laravel-permissions:migrate,这些更改将自动发生,并且您的 User 模型将如下所示

use Illuminate\Foundation\Auth\User as Authenticatable;

use IsakzhanovR\Permissions\Traits\HasPermissions;
use IsakzhanovR\Permissions\Traits\HasRoles;
use IsakzhanovR\Permissions\Contracts\PermissibleContract;
use IsakzhanovR\Permissions\Contracts\RoleableContract;

final class User  extends Authenticatable implements PermissibleContract, RoleableContract
{
    use HasRoles, HasPermissions; // add this traits to your user model

    ....
}

附加、移除和同步权限

此包允许用户与权限和角色相关联。每个角色都与多个权限相关联。在这种情况下,User 可以有一个不包含在角色权限列表中的单独的 PermissionRolePermission 是常规的 Eloquent 模型。

附加权限

因此,当创建角色时,让我们将它们分配给用户。感谢 HasRoles 特性,这使得这个过程变得非常简单

    use \App\Models\User;
    $user = User::find(1);

    // abstraction over a method $user->roles()->attach($admin->id)
    $user->attachRole($admin); // parameter can be an Role object, id or slug

    // you can also add multiple user roles
    // equivalent to $user->roles()->sync(array($admin->id, $manager->id));
    $user->attachRoles($admin,$manager,...);

方法 $user->attachRole() 接受一个参数,可以是 idslugRole 模型的实例

    $user->attachRole(1);                   // id
    //Or
    $user->attachRole('project-manager');   // slug
    //Or
    $user->attachRole(Role::find(1));       // instance of Role

    //Multiple
    $user->attachRoles(1,2,3);
    //Or
    $user->attachRoles('admin','manager','owner');
    //Or
    $user->attachRoles(Role::find(1),Role::find(2),Role::find(3));

让我们开始给角色和用户添加权限

    $admin->attachPermissions($createPost,$createNews,$updateProfile);
    $manager->attachPermissions($updatePost,$updateNews);
    $user->attachPermissions($deletePost,$deleteNews);

因此,我们为管理员和管理员角色添加了权限,并为用户提供了个人权限。

所有使用特性 HasPermission 的实体都可以访问权限关系和以下添加权限的方法

    $subject->attachPermission(1);                      // id
    //Or
    $subject->attachPermission('create-post');          // slug
    //Or
    $subject->attachPermission(Permission::find(1));    // instance of Permission

    //Multiple
    $subject->attachPermissions(1,'create-post',Permission::find(1),Permission::query()->get());

移除权限

要撤销角色和权限,请使用以下方法

    $user->detachRole(1);                   // id
    //Or
    $user->detachRole('project-manager');   // slug
    //Or
    $user->detachRole(Role::find(1));       // instance of Role

    //Multiple
    $user->detachRoles(1,'admin',Role::find(1),Role::query()->whereIn('id',[1,2,3])->get());

    $subject->detachPermission(1);                      // id
    //Or
    $subject->detachPermission('create-post');          // slug
    //Or
    $subject->detachPermission(Permission::find(1));    // instance of Permission

    //Multiple
    $subject->detachPermissions(1,2,3);

同步权限

要同步角色和权限,请使用以下方法

    $user->syncRoles([1,2,3]);            // array roles ids

    $role->syncPermissions([1,2,3,4]);    //array permissions ids

    $subject->syncPermissions([1,2,3,4]); //array permissions ids

检查权限

现在我们可以通过执行以下操作来检查角色和权限

    $user = User::find(1);

    // with role slug:
    $user->hasRole('project-manager'):bool

    // with role id:
    $user->hasRole(1):bool

    // with role instance:
    $user->hasRole(Role::find(1)): bool

您可以为每个用户拥有尽可能多的角色,反之亦然。

    $user = User::find(1);

    // with roles slug, id or instance:
    $user->hasRoles('project-manager',2, Role::find(3)):bool

    // if user has only 'admin' role return false
    $user->hasRoles('project-manager','admin'):bool

我们可以使用以下方法检查实体的权限

    $user = User::find(1);

    // with permission slug or id or instance:
    $subject->hasPermission('create-post'):bool
    // Or use `can`
    $subject->can('create-post'):bool

    // with permission slug, id or instance:
    $user->hasPermissions('create-post',2, Permission::find(3)):bool

您还可以使用占位符(通配符)通过执行以下操作来检查任何匹配的权限

    $user = User::find(1);

    // match any create permission:
    $subject->matchPermissions('create*'):bool

    // match any permission about post
    $subject->matchPermissions('*post'):bool

中间件

您可以使用中间件通过权限或角色过滤路由和路由组。在 app/Http/Kernel.php 文件的 $routeMiddleware 中添加中间件

use IsakzhanovR\Permissions\Http\Middleware\Permission;
use IsakzhanovR\Permissions\Http\Middleware\Permissions;
use IsakzhanovR\Permissions\Http\Middleware\Role;
use IsakzhanovR\Permissions\Http\Middleware\Roles;
use IsakzhanovR\Permissions\Http\Middleware\Ability;

protected $routeMiddleware = [
    // ...

    'role'        => Role::class,        // Checks for all of the specified roles.
    'roles'       => Roles::class,       // Checks for the presence of one of the specified roles.
    'permission'  => Permission::class,  // Checks whether all of the specified permissions are entered.
    'permissions' => Permissions::class, // Checks whether one of the specified permissions has been entered.
    'ability'     => Ability::class,     // Checks for matches in both roles and permissions.
]

您可以使用中间件通过权限或角色过滤路由和路由组

// Example, user has been a `seo-manager` `project-manager` roles and a `create-post` `update-post` permissions

// success access
app('router')
    ->middleware('role:project-manager,seo-manager', 'permission:create-post,update-post')
    ->get(...)

// failed access because user has not role `admin`
app('router')
    ->middleware('role:project-manager,admin')
    ->get(...)

// failed access because user has not permission `delete-post`
app('router')
    ->middleware('permission:create-post,update-post,delete-post')
    ->get(...)

如果您需要检查权限中是否存在匹配项,请使用 ability

// Example, user has been a `seo-manager` `project-manager` roles and a `create-post` `update-post` permissions

// success access
app('router')
    ->middleware('ability:*manager')
    ->get(...)

// success access
app('router')
    ->middleware('ability:*post')
    ->get(...)

// failed access because user has not permission `delete` anything
app('router')
    ->middleware('ability:delete*')
    ->get(...)

Artisan 命令

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

php artisan laravel-permissions:create-role {name}

php artisan laravel-permissions:create-permission {name}

您也可以从您的应用程序中调用创建角色和权限的创建

Artisan::call('laravel-permissions:create-role', ['name' => $name]); Artisan::call('laravel-permissions:create-permission', ['name' => $name]);

许可证

本软件包是在Andrey Helldar的监督下编写的,遵循MIT 许可证