nahid/permit

Permit 是一个 Laravel ACL 和授权包

v2.3.1 2024-02-13 09:12 UTC

This package is auto-updated.

Last update: 2024-09-13 10:15:31 UTC


README

Laravel Permit 是一个用于 Laravel 的授权和 ACL 包。它速度快,更可定制。您可以轻松处理基于角色的 ACL 或特定用户的权限。因此,让我们开始 Laravel Permit 的旅程。

安装

您可以从 composer 开始。转到您的终端,然后在项目根目录中运行以下命令。

composer require nahid/permit

稍等片刻,它会下载所有依赖项。

配置

完成安装后,您需要配置它。首先复制这些行,将其粘贴到 config/app.php 文件中,其中存在 providers 数组。

Nahid\Permit\PermitServiceProvider::class,

然后添加对门面支持的行

'Permit'    => Nahid\Permit\Facades\Permit::class,

现在,您必须运行此命令以发布必要的文件。

php artisan vendor:publish --provider="Nahid\Permit\PermitServiceProvider"

然后转到 config/permit.php 并使用您的首选凭据进行编辑。

return [
    'users' => [
        'model' => \App\Models\User::class,
        'table' => 'users',
        'role_column'   => 'type'
    ],

    'super_user'    =>  'admin',

    'abilities'   => [
       // "module"  => ['ability1', 'ability2', 'ability3'=>'policy_module.policy'],
    ],


    'policies'  => [
        /*'module' => [
            'update'    => '\App\Permit\Policies\PostPolicy@update',
        ],*/
    ],



    'roles' => [
        /*'role_name' => [
            'module.ability',
        ],*/
    ]
];

现在运行此命令进行迁移

php artisan migrate

您即将完成,只需将此 trait Nahid\Permit\Users\Permitable 添加到您的 User 模型中。示例

namespace App;

use Illuminate\Database\Eloquent\Model;
use Nahid\Permit\Users\Permitable;

class User extends Model
{
    use Permitable;
}

是的,完成了。

它是如何工作的?

这是一个常见问题。但首先,您必须了解我们的数据库架构。当您运行迁移命令时,我们创建一个名为 'permissions' 的表,其中包含字段 'role_name' 和 'permission',并在 users 表中添加两个列 'role' 和 'permissions'。列 role 存储用户的角色,列 permissions 存储特定于用户的控制。在这里,列 rolepermissions.role_name 列及其控制相关联。permissions.permission 处理基于角色的控制。

我们以 JSON 格式存储权限,其中包含特定的模块和能力。

{
    "user": {
        "create": true,
        "update": true
    },
    "post": {
        "create": false,
        "update":"\\App\\Permit\\Policies\\PostPolicy@update",
        "delete": true
    }
}

在这里,userpost 是服务/模块名称,而 createupdatedelete 或其他是能力。

设置用户角色

语法

bool Permit::setUserRole(int $user_id, string $role_name)

示例
Permit::setUserRole(1, 'admin');

设置用户权限

语法

bool Permit::setUserPermissions(int $user_id, string $module, array $abilities)

示例
Permit::setUserPermissions(1, 'post', ['create'=>true, 'update'=>true]);

设置角色权限

语法

bool Permit::setRolePermissions(string $role_name, string $module, array $abilities)

示例
Permit::setRolePermissions('admin', 'post', ['create'=>true, 'update'=>true]);

如何授权事件?

检查用户能力

$user = User::find(1);

if (Permit::userCan($user, 'post.create')) {
    //do something
}

post.create 事件中有一个模块/服务。这里 post 是模块,create 是能力。

因此,如果用户已授权 post 创建事件,则用户将通过。

Permit::userCan() 方法返回布尔值。如果您想抛出未授权异常,可以使用

Permit::userAllows() 使用相同的参数。

检查用户角色能力

$user = User::find(1);

if (Permit::roleCan($user, 'post.create')) {
    //do something
}

在这里,当给定的用户角色允许此事件时,它将通过。这里有类似的方法来抛出异常

Permit::roleAllows()

检查用户所有能力

您可以从用户或用户角色检查用户能力。在这里,我们检查了用户和角色的权限,但如果设置了特定于用户的权限,则其优先级将更高。

$user = User::find(1);

if (Permit::can($user, 'post.create')) {
    //do something
}

这里是抛出异常的替代方法

Permit::allows()

策略

策略是一个类似于 Laravel 原生授权的功能,但它相当简单。Permit 允许您在一条线上管理 ACL 和授权。我知道您第一个问题是我们在哪里使用 Policy

让我们看一个例子,假设您有一个用户评论系统,其中每个用户都可以在博客文章下评论,并且评论所有者可以编辑和删除他们的评论。因此,您必须应用一个授权系统,其中用户可以修改他/她的评论。因此,在这里,我们必须实现我们自己的策略。看看这个

制定策略

首先,我们需要为策略创建一个类。

namespace App\Policies;

use App\Comment;
use App\User;

class CommentPolicy
{
    public function update(User $user, Comment $comment)
    {
        return $user->id == $comment->user_id;
    }
}

现在将此策略映射到我们的配置文件。转到 config/permit.php 并更新 `policies` 部分的内容

    ,'policies'  => [
        'comment'  => [
            'update'    => '\App\Policies\CommentPolicy@update'
        ]
    ]

现在您需要将此策略绑定到一个能力上。假设我们有一个关于评论的模块,那么这个能力在 config/permit.phpabilities 部分看起来像这样

"comment"  => ['create', 'update'=>'comment.update', 'delete'],

这里 'update'=>'comment.update',其中 "update" 是一个能力,而 "comment.update" 是一个策略。这个系统将策略绑定到能力上,因此现在您可以像使用一般能力一样使用这个策略。

您可以在配置文件中预先定义所有角色的权限。首先设置您的近似能力,然后分配能力到角色。看看下面

'abilities'   => [
        "comment"  => ['create', 'update'=>'comment.update', 'delete'],
        "user"  => ['create', 'update', 'delete'],
    ],

    'roles' => [
        'admin' => [
            'post.*',
            'user.*',
        ],

        'user'    => [
            'post.create',
            'post.update',
            'user.create',
            'user.update',
        ]
    ],

    'policies'  => [
        'comment'  => [
            'update'    => '\App\Policies\CommentPolicy@update'
        ]
    ]

这里 "admin" 和 "user" 是角色,其值是权限或能力。但是您不能使用它,因为它没有与数据库同步。因此,从您的终端运行此命令

php artisan permit:sync

如何使用基于策略的能力

在上一节中,我们将 comment.update 策略与一个能力绑定,并且它们的名称相同。让我们检查当前打开的评论是否被登录用户授权。

$comment = Comment::find(1);
Permit::allows(auth()->user(), 'comment.update', [$comment]);

这里第一个参数是授权用户,第二个是权限,第三个是策略方法的参数。我们始终自动将认证用户绑定为第一个参数,然后传递其他参数。

您可以使用其他方法,如 roleCan、'userCan'、所有辅助函数和 blade 指令,按照相同的流程。

有时您需要检查指定的用户是否有权执行任何能力。我们使其变得简单。让我们看看

Permit::allows(auth()->user(), ['post.create', 'comment.create']);

但是,如果您的能力绑定了一个策略并且需要参数,那么您可以使用关联数组传递能力。

$comment = Comment::find(1);
Permit::allows(auth()->user(), ['post.create', 'comment.update'=>[$comment], 'comment.create']);

这里,如果指定的用户被分配到任何能力,则允许。

命令

我们提供了几个命令来提高用户体验

php artisan permit:sync

与数据库同步您的组合权限。

php artisan permit:set

向用户或角色添加权限

php artisan permit:remove

从用户或角色中删除权限

php artisan permit:fetch

获取用户或角色的权限

php artisan permit:role

创建新角色

辅助函数

您可以使用辅助函数而不是外观。

user_can()

您可以使用 user_can() 代替 Permit::userCan()

user_allows()

您可以使用 user_allows() 代替 Permit::userAllows()

role_can()

您可以使用 role_can() 代替 Permit::roleCan()

role_allows()

您可以使用 role_allows() 代替 Permit::roleAllows()

canDo()

您可以使用 canDo() 代替 Permit::can()

allows()

您可以使用 allows() 代替 `Permit::allows()`

Blade 指令

有时您可能希望在视图中使用这些功能。Permit 包含所有 blade 指令。

示例

@userCan($user, 'post:create')
    <a href="#">Link</a>
@endUserCan

您也可以使用 else 指令

@userCan($user, 'post:create')
    <a href="#">Link</a>
@elseDo
    <a href="#">Link 2</a>
@endUserCan

指令列表

  • @userCan()
  • @elseUserCan
  • @endUserCan()
  • @roleCan()
  • @elseRoleCan
  • @endRoleCan()
  • @allows()
  • @endAllows()
  • @elseAllows()

如果您有任何疑问,请随时与我分享

谢谢