Laravel Authorization:支持 ACL、RBAC、ABAC 等模型的授权库

Laravel Authorization 基于 Casbin ,是一个支持访问多种访问控制模型(如 ACL,RBAC,ABAC 等)的授权库。
在这之前,你需要先了解 Casbin

安装#

使用 Composer 安装:

composer require casbin/laravel-authz

Lauthz\LauthzServiceProviderauto-discovered 的,并且默认情况下已注册,但是如果您想自己注册,可以在 config/app.php 中添加 ServiceProvider:

'providers' => [
    /*
     * Package Service Providers...
     */
    Lauthz\LauthzServiceProvider::class,
]

Enforcer facade 也是 auto-discovered,但是如果您想手动添加它,在 config/app.php 添加:

'aliases' => [
    // ...
    'Enforcer' => Lauthz\Facades\Enforcer::class,
]

要发布配置,请运行 vendor:publish 命令:

php artisan vendor:publish

这就自动创建 Model 配置文件 config/lauthz-rbac-model.conf 和 一个新的 Lauthz 配置文件 config/lauthz.php

要迁移迁移,请运行 migrate 命令:

php artisan migrate

这将创建一个 rules 数据表。

用法#

快速开始#

安装后,您可以执行以下操作:


use Enforcer;

// adds permissions to a user
Enforcer::addPermissionForUser('eve', 'articles', 'read');
// adds a role for a user.
Enforcer::addRoleForUser('eve', 'writer');
// adds permissions to a rule
Enforcer::addPolicy('writer', 'articles','edit');

您可以校验用户的权限,如下:

// to check if a user has permission
if (Enforcer::enforce("eve", "articles", "edit")) {
    // permit eve to edit articles
} else {
    // deny the request, show an error
}

使用 Enforcer Api#

它提供了非常丰富的 API,以促进对 Policy 的各种操作:

获取所有角色:

Enforcer::getAllRoles(); // ['writer', 'reader']

获取所有的角色的授权规则:

Enforcer::getPolicy();

获取某个用户的所有角色:

Enforcer::getRolesForUser('eve'); // ['writer']

获取某个角色的所有用户:

Enforcer::getUsersForRole('writer'); // ['eve']

决定用户是否拥有某个角色:

Enforcer::hasRoleForUser('eve', 'writer'); // true or false

给用户添加角色:

Enforcer::addRoleForUser('eve', 'writer');

赋予权限给某个用户或角色:

// to user
Enforcer::addPermissionForUser('eve', 'articles', 'read');
// to role
Enforcer::addPermissionForUser('writer', 'articles','edit');

删除用户的角色:

Enforcer::deleteRoleForUser('eve', 'writer');

删除某个用户的所有角色:

Enforcer::deleteRolesForUser('eve');

删除单个角色:

Enforcer::deleteRole('writer');

删除某个权限:

Enforcer::deletePermission('articles', 'read'); // returns false if the permission does not exist (aka not affected).

删除某个用户或角色的权限:

Enforcer::deletePermissionForUser('eve', 'articles', 'read');

删除某个用户或角色的所有权限:

// to user
Enforcer::deletePermissionsForUser('eve');
// to role
Enforcer::deletePermissionsForUser('writer');

获取用户或角色的所有权限:

Enforcer::getPermissionsForUser('eve'); // return array

觉得某个用户是否拥有某个权限:

Enforcer::hasPermissionForUser('eve', 'articles', 'read');  // true or false

更多 API 参考 Casbin API

使用中间件#

该扩展包带有 EnforcerMiddlewareRequestMiddleware 中间件。 您可以将它们添加到您的 app/Http/Kernel.php 文件中:

protected $routeMiddleware = [
    // ...
    // a basic Enforcer Middleware
    'enforcer' => \Lauthz\Middlewares\EnforcerMiddleware::class,
    // an HTTP Request Middleware
    'http_request' => \Lauthz\Middlewares\RequestMiddleware::class,
];

基本 Enforcer 中间件#

然后就可以使用它们来保护路由了:

Route::group(['middleware' => ['enforcer:articles,read']], function () {
    // pass
});

HTTP 请求中间件 (支持 RESTful)#

如果需要授权一个请求,则需要首先在 config/lauthz-rbac-model.conf 中定义模型配置:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && regexMatch(r.act, p.act)

然后,使用中间件规则:

Route::group(['middleware' => ['http_request']], function () {
    Route::resource('photo', 'PhotoController');
});

多个决策器#

如果您的项目中需要多个权限控制,则可以配置多个 决策器

lauthz 配置文件中, 应该这样配置:

return [
    'default' => 'basic',

    'basic' => [
        'model' => [
            // ...
        ],

        'adapter' => Lauthz\Adapters\DatabaseAdapter::class,
        // ...
    ],

    'second' => [
        'model' => [
            // ...
        ],

        'adapter' => Lauthz\Adapters\DatabaseAdapter::class,
        // ...
    ],
];

然后选择使用哪一个决策器:

Enforcer::guard('second')->enforce("eve", "articles", "edit");

Artisan 命令行#

你可以在 控制台 使用 artisan 命令创建策略:

给用户添加策略:

php artisan policy:add eve,articles,read

给角色添加策略:

php artisan policy:add writer,articles,edit

给用户赋予角色:

php artisan role:assign eve writer

缓存#

缓存 授权 规则可以提升性能,默认是关闭的。

在 Laravel 的 config/lauthz.php 中设置自己的缓存配置:

'cache' => [
    // changes whether Lauthz will cache the rules.
    'enabled' => false,

    // cache store
    'store' => 'default',

    // cache Key
    'key' => 'rules',

    // ttl \DateTimeInterface|\DateInterval|int|null
    'ttl' => 24 * 60,
],

最后#

Casbin 项目地址:github.com/php-casbin/php-casbin

Laravel Authorization 项目地址:github.com/php-casbin/laravel-auth...

你可以查看 Casbin 的完整文档 Casbin Docs.

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 12

兄弟,文章你好像没翻译全,建议把这些也翻译了,这样会更加直观。

file

5年前 评论
JonLee (楼主) 5年前
犯二青年 (作者) 5年前

如何将配置文件的东西放到数据库,变成可视化配置。

4年前 评论
JonLee (楼主) 4年前

你好,问下 casbin 有没有 hyperf 的组件?前后分离的话,前端的权限后端该如何实现给前端做处理,希望之指点下,谢谢

4年前 评论

今天开始学习 casbin, 看了很久不太明白 如何把角色和 API 的方案关联进去

4年前 评论
JonLee (楼主) 4年前
$role = $this->getRoles($id);
        if (!empty($role)) {
            foreach ($role as $item) {
                Log::info($this->permissionService->getIdentifier($item['id']) . '==='. $route . '==='. $method);
                if (Enforcer::enforce($this->permissionService->getIdentifier($item['id']), $route, $method)) {
                    return true;
                } else {
                    return false;
                }
            }
        } else {
            return false;
        }

报以下错误,是我哪里用的不对吗

array_combine(): Both parameters should have an equal number of elements {"userId":9,"exception":"[object] (ErrorException(code: 0): array_combine(): Both parameters should have an equal number of elements at /Users/ly/www/laravel-admin/vendor/casbin/casbin/src/CoreEnforcer.php:645)
3年前 评论
JonLee (楼主) 3年前
phpxcn (作者) 3年前