kordy/auzo-tools

此包已被废弃,不再维护。未建议替代包。

辅助函数,使管理Laravel授权变得非常容易,并提供集中式授权管理。兼容Laravel版本5.1、5.2和5.3。

安装: 277

依赖: 1

建议者: 0

安全: 0

星标: 4

关注者: 3

分支: 0

开放问题: 1

类型:package

1.1.1 2016-11-06 08:54 UTC

This package is auto-updated.

Last update: 2021-05-06 01:54:02 UTC


README

此包是Laravel 5.1、5.2和5.3的一系列工具,用于简化您Laravel项目或包的授权管理。您可以使用AuzoTools管理项目中的授权,或为您的包用户提供可配置的授权选项。

包含的工具

  1. 管理Laravel授权。
  2. 模型自动能力生成器。
  3. 路由授权中间件。
  4. 控制器授权验证规则。
  5. 模型字段策略。

安装

您可以通过Composer安装此包

composer require kordy/auzo-tools

必须安装此服务提供者。

// config/app.php
'providers' => [
    ...
    Kordy\AuzoTools\AuzoToolsServiceProvider::class,
];

您可以使用以下命令发布翻译

php artisan vendor:publish --provider="Kordy\AuzoTools\AuzoToolsServiceProvider" --tag="translations"

您可以使用以下命令发布配置文件

php artisan vendor:publish --provider="Kordy\AuzoTools\AuzoToolsServiceProvider" --tag="config"

使用

管理Laravel授权

AuzoTools可以帮助您管理任何数量的资源的能力,并管理谁可以访问它们的限制策略。您可以使用AuzoTools来管理项目中的授权,或为包用户提供可配置的授权选项。

参数函数可以作为策略,因此当AuzoTools评估用户对资源/模型记录的访问时,它将把这些信息传递到您指定的函数,您的函数将评估用户信息与想要访问的资源进行比较,然后返回一个布尔决策,以决定是否允许用户访问。

请参阅测试文件中的示例。

您有两种方式定义策略,要么是回调,要么是专用类方法。

1. 回调策略

创建如下配置文件

// config/acl.php

return [
    'before' => [
        function($user, $ability) {
            return $user->id == 1;
        }
    ],
    'abilities' => [

        'post.update' => [
            function($user, $ability, $model) { return $user->id == 3; },
            ['or' => function ($user, $ability, $model) { return $user->id == 2; }],
        ],

        'post.destroy' => [
            function ($user, $ability, $model) { return $user->id == 2; },
        ],
    ],
    // use this to log or monitor authorization given to users
    //  you may not modify the result of the authorization check from an after callback
    'after' => [
        function ($user, $ability, $result, $arguments = null)
        {
            if ($result) {
                \Log::info("Authorization Log: User $user->name ($user->email) is granted access to ability $ability at ".date('d-m-Y H:j'));
            } else {
                \Log::info("Authorization Log: User $user->name ($user->email) is forbidden to access ability $ability at ".date('d-m-Y H:j'));
            }
        },
    ],
];

2. 专用类方法

创建如下配置文件

// config/acl.php

return [
    'before' => [
        'App\MyPolicyClass@isAdmin'
    ],
    'abilities' => [

        'post.update' => [
            'App\MyPolicyClass@postOwner',
            ['or' => 'App\MyPolicyClass@isModerator']
        ],

        'post.destroy' => [
            'App\MyPolicyClass@isModerator'
        ],
    ],
    // use this to log or monitor authorization given to users
    //  you may not modify the result of the authorization check from an after callback
    'after' => [
        'App\MyPolicyClass@monitor'
    ],
];

创建一个包含策略方法的策略类

<?php

namespace App;

class MyPolicyClass
{
/**
     * Check if user is admin
     *
     * @param $user
     * @param $ability
     * @return bool
     */
    public function isAdmin($user, $ability) {
        return $user->id == 1;
    }

    /**
     * Check if user is moderator
     *
     * @param $user
     * @param $ability
     * @return bool
     */
    public function isModerator($user, $ability) {
        return $user->role == 'moderator';
    }

    /**
     * Check if user is post owner
     *
     * @param $user
     * @param $ability
     * @return bool
     */
    public function postOwner($user, $ability, $post) {
        if ($post instanceOf Post) {
            return $user->id == $post->user_id;
        } 
        
        // If middleware passed you the user request instead of the model 
        // instance, get the resource information from the request
        if ($post === null || $post instanceof Request) {
            $postId = request()->route('id');
            $post = Post::find($postId);
            return $user->id == $post->user_id;
        }
    }

    /**
     * Run authorization monitor, see storage/logs/laravel.log
     *
     * @param $user
     * @param $ability
     */
    public function monitor($user, $ability, $result, $arguments = null)
    {
        if ($result) {
            \Log::info("Authorization Log: User $user->name ($user->email) is granted access to ability $ability at " . date('d-m-Y H:j'));
        } else {
            \Log::info("Authorization Log: User $user->name ($user->email) is forbidden to access ability $ability at " . date('d-m-Y H:j'));
        }
    }
}

最后

在服务提供者中运行\AuzoToolsPermissionRegistrar::registerPermissions($abilities_policies)以在启动时将能力加载到Laravel Gate

// app/Providers/AppServiceProvider.php

public function boot()
{
    // Load abilities to Laravel Gate
    $abilities_policies = config('acl');
    \AuzoToolsPermissionRegistrar::registerPermissions($abilities_policies);
}

现在您可以在项目或包的任何位置授权用户

$user->can('post.show', $post)
// or
$user->cannot('post.update', $post)
// or for current logged in user
Gate::allows('post.update', Post::findOrFail($postId));

更多信息:https://laravel.net.cn/docs/master/authorization#authorizing-actions-using-policies

自动能力生成器

给它一个名字,它会自动生成与默认路由资源名称或自定义名称匹配的能力名称。

为模型生成 CRUD 能力

$generator = GenerateAbilities::modelAbilities('testuser');
$generated_abilities = $generator->model_crud_abilities;

这将根据每个路由路径生成能力名称

[
    'index'     => 'testuser.index',
    'create'    => 'testuser.create',
    'store'     => 'testuser.store',
    'show'      => 'testuser.show',
    'edit'      => 'testuser.edit',
    'update'    => 'testuser.update',
    'destroy'   => 'testuser.destroy',
]

在 config/auzo-tools.php 中,您可以修改要生成的路由路径的 CRUD

'crud' => ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy']

为模型字段生成 CRUD 能力

它还可以生成模型字段的完整能力列表,如下所示

$generator = GenerateAbilities::fieldsAbilities(App\User::class)
$generated_fields_abilities = $generator->fields_crud_abilities;

这将根据每个模型路由路径为每个模型列生成能力名称

[
    'id' => [
        'index'     => 'user.index.id',
        'create'    => 'user.create.id',
        'store'     => 'user.store.id',
        'show'      => 'user.show.id',
        'edit'      => 'user.edit.id',
        'update'    => 'user.update.id',
        'destroy'   => 'user.destroy.id'
    ],
    'name' => [
        'index'     => 'user.index.name',
        'create'    => 'user.create.name',
        'store'     => 'user.store.name',
        'show'      => 'user.show.name',
        'edit'      => 'user.edit.name',
        'update'    => 'user.update.name',
        'destroy'   => 'user.destroy.name'
    ],
    'email' => [
        'index'     => 'user.index.email',
        'create'    => 'user.create.email',
        'store'     => 'user.store.email',
        'show'      => 'user.show.email',
        'edit'      => 'user.edit.email',
        'update'    => 'user.update.email',
        'destroy'   => 'user.destroy.email'
    ],
    'password' => [
        'index'     => 'user.index.password',
        'create'    => 'user.create.password',
        'store'     => 'user.store.password',
        'show'      => 'user.show.password',
        'edit'      => 'user.edit.password',
        'update'    => 'user.update.password',
        'destroy'   => 'user.destroy.password'
    ],
    'remember_token' => [
        'index'     => 'user.index.remember_token',
        'create'    => 'user.create.remember_token',
        'store'     => 'user.store.remember_token',
        'show'      => 'user.show.remember_token',
        'edit'      => 'user.edit.remember_token',
        'update'    => 'user.update.remember_token',
        'destroy'   => 'user.destroy.remember_token'
    ],
    'created_at' => [
        'index'     => 'user.index.created_at',
        'create'    => 'user.create.created_at',
        'store'     => 'user.store.created_at',
        'show'      => 'user.show.created_at',
        'edit'      => 'user.edit.created_at',
        'update'    => 'user.update.created_at',
        'destroy'   => 'user.destroy.created_at'
    ],
    'updated_at' => [
        'index'     => 'user.index.updated_at',
        'create'    => 'user.create.updated_at',
        'store'     => 'user.store.updated_at',
        'show'      => 'user.show.updated_at',
        'edit'      => 'user.edit.updated_at',
        'update'    => 'user.update.updated_at',
        'destroy'   => 'user.destroy.updated_at'
    ]
]

将生成的能力作为 JSON 字符串保存到文件中

将结果编码为 JSON 字符串并保存到指定的文件路径

$file_path = config_path('abilities/generated_abilities.json');
// This will faltten the output array
GenerateAbilities::fullCrudAbilities($model)->writeToFile($file_path);
// This will not faltten the output array
GenerateAbilities::fullCrudAbilities($model)->writeToFile($file_path, false);

扁平化输出

[
    "user.index", "user.create", "user.store", "user.show", "user.edit", "user.update",
    "user.destroy", "user.index.id", "user.create.id", "user.store.id", "user.show.id",
    "user.edit.id", "user.update.id", "user.destroy.id", "user.index.name", "user.create.name",
    "user.store.name", "user.show.name", "user.edit.name", "user.update.name",
    "user.destroy.name", "user.index.email", "user.create.email", "user.store.email",
    "user.show.email", "user.edit.email", "user.update.email", "user.destroy.email",
    "user.index.password", "user.create.password", "user.store.password", "user.show.password",
    "user.edit.password", "user.update.password", "user.destroy.password",
    "user.index.remember_token", "user.create.remember_token", "user.store.remember_token",
    "user.show.remember_token", "user.edit.remember_token", "user.update.remember_token",
    "user.destroy.remember_token", "user.index.created_at", "user.create.created_at",
    "user.store.created_at", "user.show.created_at", "user.edit.created_at",
    "user.update.created_at", "user.destroy.created_at", "user.index.updated_at",
    "user.create.updated_at", "user.store.updated_at", "user.show.updated_at",
    "user.edit.updated_at", "user.update.updated_at", "user.destroy.updated_at"
]

路由授权中间件

这是一个路由中间件,可以与路由或 Http 控制器一起使用,在访问请求的资源之前检查用户授权。

使用参数使用它

Route::get('user-profile-test', function (){
    return 'hello there';
})->middleware('auzo.acl:user-profile');

这将检查用户是否有 'user-profile' 的授权能力

自动授权检查

Route::get('user-profile-test/{id}', 'Controller@action')
       ->name('user.profile.test')->middleware('auzo.acl');

使用 命名路由,您可能无需参数即可使用中间件进行自动授权。

  1. 它将检查用户是否被授权访问路由名称 user.profile.test
  2. 如果路由没有名称,则将检查与 Controller@action 的匹配

控制器授权验证规则

这是一个自定义验证规则 auzo.can,它检查用户是否授权针对传递的参数的字段能力名称。

$v = Validator::make($data, [
    'someField' => 'auzo.can:test.ability.someField',
]);

如果用户未授权,将生成验证错误,要修改生成的错误消息,请修改 resource/lang/vendor/auzo-tools/en/validation.php

return [
    'can' => 'You are not authorized to modify :attribute !',
];

模型字段策略

对于 API 非常有用,您可以在将模型数据发送给用户之前,根据用户授权更改隐藏、可填充和受保护的列。

首先确保您已将 ModelFieldsPoilcy trait 添加到您的模型中。

use Kordy\AuzoTools\Traits\ModelFieldsPolicy;

示例:在您的模型文件中,在类声明之后添加此内容

class SomeModel extends Model {

    use Kordy\AuzoTools\Traits\ModelFieldsPolicy;

传递模型能力修正,以便它检查附加到能力修正的每个字段名称,并检查用户是否被授权生成的能力。

因此,如果模型具有字段 nameemailpassword,并且您传递 user.show 修正,那么它将检查授权:

检查 name 字段,如果用户有 user.show.name 能力

检查 email 字段,如果用户有 user.show.email 能力

检查 password 字段,如果用户有 user.show.password 能力,依此类推。

使未授权的列隐藏

$model->hideFieldsByPolicy('user.show');

使未授权的列不可填充

$model->fillableFieldsByPolicy('user.show');

使未授权的列受保护

$model->guardFieldsByPolicy('user.show');

贡献

请参阅 CONTRIBUTING 了解详细信息。

许可

麻省理工学院许可证(MIT)。有关更多信息,请参阅许可证文件