kordy / auzo-tools
辅助函数,使管理Laravel授权变得非常容易,并提供集中式授权管理。兼容Laravel版本5.1、5.2和5.3。
Requires
- laravel/framework: ^5.1
Requires (Dev)
- phpunit/phpunit: ^4.0|^5.0
This package is auto-updated.
Last update: 2021-05-06 01:54:02 UTC
README
此包是Laravel 5.1、5.2和5.3的一系列工具,用于简化您Laravel项目或包的授权管理。您可以使用AuzoTools管理项目中的授权,或为您的包用户提供可配置的授权选项。
包含的工具
安装
您可以通过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');
使用 命名路由
,您可能无需参数即可使用中间件进行自动授权。
- 它将检查用户是否被授权访问路由名称
user.profile.test
- 如果路由没有名称,则将检查与
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;
传递模型能力修正,以便它检查附加到能力修正的每个字段名称,并检查用户是否被授权生成的能力。
因此,如果模型具有字段 name
、email
、password
,并且您传递 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)。有关更多信息,请参阅许可证文件。