michaeltintiuc / laravel-permy
基于定义的路由的Laravel用户权限(角色或组)。
Requires
- php: >=5.4.0
- illuminate/support: >=4.2.0
README
简称“永久朋友”——我妈说我这么做挺酷的!
为您的所有Laravel应用程序提供强大且灵活的ACL;支持4.2版本及以上
- 将单个或多个权限分配给用户,并通过
AND、OR或XOR运算符控制继承逻辑 - 使用多个用户模型
- 通过支持本地化的UI或数据库管理权限
- 通过过滤器/中间件直接在路由、路由组或控制器上设置权限
- 使用额外的逻辑运算符进行批处理权限检查
- Artisan命令和调试助手
待办事项
- 类重构和抽象化
- 为Artisan命令添加对数组权限的运算符键支持
- 额外的辅助Artisan命令
- 添加PHP7类型提示
- 改进数据库访问,最小化查询次数
- 添加Blade指令
内容
唯一一个没有滑稽注释的部分
安装
美丽友谊的开始(背景音乐很俗气)
通过composer要求
composer require michaeltintiuc/laravel-permy
对于Laravel 5.5+,您不需要手动添加服务提供者或外观(别名)——这些将自动发现
将服务提供者追加到您的app/config/app.php中的提供者数组(4.2)或config/app.php(5.0+)
'MichaelT\Permy\PermyServiceProvider'
将外观追加到您的app/config/app.php中的外观数组(4.2)或config/app.php(5.0+)
'Permy' => 'MichaelT\Permy\PermyFacade'
将特质添加到您的用户模型或任何其他需要权限的模型中。
use MichaelT\Permy\PermyTrait; class User extends Model { use PermyTrait; }
发布
我不能再发布这个了...
迁移
Laravel 4.2
php artisan migrate:publish michaeltintiuc/laravel-permy
Laravel 5.0+
php artisan vendor:publish --provider="MichaelT\Permy\PermyServiceProvider" --tag="migrations"
配置
这是一个可选步骤,配置文件的说明将在下面跟随
Laravel 4.2
php artisan config:publish michaeltintiuc/laravel-permy
Laravel 5.0+
php artisan vendor:publish --provider="MichaelT\Permy\PermyServiceProvider" --tag="config"
翻译
这是一个可选步骤,语言文件的配置将在下面跟随
Laravel 4.2
创建文件app/lang/packages/en/laravel-permy/defaults.php
您可以为您的应用程序使用的每个区域创建此文件,只需将en替换为fr(例如)即可
Laravel 5.0+
php artisan vendor:publish --provider="MichaelT\Permy\PermyServiceProvider" --tag="translations"
数据库
放下基础,等等!不,我的意思不是这个!
在您成功发布迁移文件后,您应该有2个文件
create_permy_table和create_permy_user_table
permy表负责存储您未来的所有权限,而permy_user表则包含用户与其相应权限之间的关系
Permy以一种方式工作,即每个权限都有一个名称、描述和许多列,每列代表一个具有受限用户访问权限的控制器。现在让我们来配置它。
保留样板代码不变
$table->increments('id'); $table->string('name'); $table->string('desc');
为每个需要访问限制的控制器创建一个列。我们指定将使用Permy中间件/过滤器的控制器。这些应该是完全命名空间类名,并且将\(反斜杠)替换为::(双冒号)
原始控制器类名
Acme\Controllers\UsersController
生成的php和列名
$table->text('Acme::Controllers::UsersController')->nullable();
列类型是 text,因为我们将会存储表示对特定控制器方法访问的 JSON 数据。我们还设置了列为 可为空,因为...你可能忘了你为你的出色功能创建了几个新的控制器和/或方法,这将允许优雅地回退到限制或允许访问(我们稍后将会详细讨论)。
现在你已经设置好了 - 更新你的数据库
php artisan migrate
使用方法
我知道,最后...但这是值得的,我保证!
中间件/过滤器
Laravel 4.2
将过滤器添加到你的 app/filters.php 文件的末尾
Route::filter('permy', 'MichaelT\Permy\PermyFilter');
Laravel 5.0+
将中间件添加到你的 app/Http/Kernel.php 文件中的 $routeMiddleware 数组
'permy' => 'MichaelT\Permy\PermyMiddleware'
这是一个基本的过滤器/中间件,它将在受限路由上简单地返回 403 - 禁止访问。如果你想显示自定义文本、视图或者可能是一个重定向,你可以提供一个自己的类。你只需要在你的实现中使用 Permy::can($route) 执行一个检查。查看 过滤器 或 中间件 的源代码以及 Laravel 文档 4.2、5.0+ 来了解如何实现自定义过滤器。
路由 & 控制器
Laravel 4.2
这些 必须 在 过滤器 之前
直接应用于路由
Route::get('/', ['before' => 'permy', 'uses' => 'SomeController@method']);
或路由组
Route::group([before' => 'permy'], function () { ... });
或控制器内部
class SomeController { public function __construct() { $this->beforeFilter('permy'); // checks all methods $this->beforeFilter('permy', array('only' => 'index')); // checks only index method $this->beforeFilter('permy', array('except' => 'index')); // checks all but the index method } }
Laravel 5.0+
直接应用于路由
Route::get('/', 'SomeController@method')->middleware('permy');
或路由组
Route::group([middleware' => 'permy'], function () { ... });
或控制器内部
class SomeController { public function __construct() { $this->middleware('permy'); // checks all methods $this->middleware('permy')->only('index'); // checks only index method $this->middleware('permy')->except('index'); // checks all but the index method } }
到这里你就完成了,可以测试应用程序。如果你已经将过滤器/中间件分配给了 Acme\SomeController,它有 index 和 someMethod 方法,你可以在 permy 表中插入一个新的行,为 Acme::SomeController 列提供一个测试 JSON
{"index": 1, "someMethod": 0}
注意新行的 ID,并在 permy_user 表中插入一个新的行,将权限 ID 绑定到现有的用户。这将允许分配的用户对 index 方法发出请求并阻止访问 someMethod。如果你尝试使用不同的用户执行上述路由,所有请求都将被阻止,实际上对未明确设置的方法的任何请求也将被阻止。这种行为可以通过配置文件来覆盖。
方法
can
boolean can(<array|string|Illuminate\Routing\Route $routes> [, [string $operator = 'and'] [, boolean|callable $extra_check = true]])
允许你检查当前用户是否可以访问一个或多个路由或控制器方法。你可以混合传递数组时的路由名称、控制器类名/方法以及路由对象。
基本
// check single route or controller method Permy::can('users.index'); Permy::can('UsersController@index'); // check multiple routes or controller methods // returns true if ALL routes/methods are allowed Permy::can(['users.index', 'users.show']); Permy::can(['UsersController@index', 'UsersController@show']); // OR returns true if at least 1 route/method is accessible Permy::can(['users.index', 'users.show', 'operator' => 'or']); Permy::can(['UsersController@index', 'UsersController@show', 'operator' => 'or']); // XOR the permission values of each route/method Permy::can(['users.index', 'users.show', 'operator' => 'xor']); Permy::can(['UsersController@index', 'UsersController@show', 'operator' => 'xor']);
高级
你可以在结果权限上执行额外的逻辑运算。
// Additional check $check = SomeClass::checkUser(); // return true if permissions AND $check are true Permy::can('users.index', 'and', $check); // At least one should be true Permy::can('users.index', 'or', $check); // XOR the values of permissions and $check Permy::can('users.index', 'xor', $check); // Omit the $operator and use the default value Permy::can('users.index', $extra_check = $check); // Provide a callback function // The return value will be type hinted to boolean Permy::can('users.index', $extra_check = function () { return SomeClass::fetchData(); });
cant
boolean cant(<array|string|Illuminate\Routing\Route $routes> [, [string $operator = 'and'] [, boolean|callable $extra_check = true]])
与 can() 相同,这是一个辅助函数。
// returns false if access is allowed Permy::cant('users.index');
getList
array getList()
对所有具有 fillable 过滤器/中间件分配的路由和控制器执行检查。构建一个本地化的控制器/方法名称和描述的数组。创建/更新翻译文件。
在检索用于 UI 管理的权限数据时很有用。
// Generates language file for default locale Permy::getList(); // Generates language file for 'fr' locale App::setLocale('fr'); Permy::getList(); // When setting locale explicitly - reset it when done // Whichever is fine App::setLocale(Config::get('app.fallback_locale')); App::setLocale('en');
setUser
PermyHandler setUser(<Illuminate\Database\Eloquent\Model $user>)
提供一个特定的用户而不是默认的已验证用户
$user = User::find(123); // Check if user ID 123 has access Permy::setUser($user)->can('users.index'); // Next calls will check the authenticated user NOT the one we've set before Permy::can('users.index');
getUser
Illuminate\Database\Eloquent\Model getUser()
用于测试/调试的辅助函数
$user = User::find(123); // returns user ID 123 Permy::setUser($user)->getUser(); // returns currently authenticated user Permy::getUser();
setDebug
PermyHandler setDebug(<boolean $bool>)
覆盖当前调用的配置值(有关详细信息,请参阅配置文档)
// Debugging is on Permy::setDebug(true)->can('users.index'); // Debugging is equal to value set in config Permy::can('users.index');
setGodmode
PermyHandler setGodmode(<boolean $bool>)
所有检查都返回 true。为什么不呢?(请参阅配置文档以获取详细信息)
// Returns true even if access is disallowed Permy::setGodmode(true)->can('users.index'); // Godmode is equal to value set in config Permy::can('users.index');
setRolesLogicOperator
PermyHandler setRolesLogicOperator(<string $operator>)
覆盖当前调用的配置值(有关详细信息,请参阅配置文档)
// At least one of the permissions assigned allows access to users.index Permy::setRolesLogicOperator('or')->can('users.index'); // Value from config is used now Permy::can('users.index');
配置
还有更多吗?
logic_operator
如果用户分配了多个权限,并且每个路由/方法存在冲突的权限,应使用哪个逻辑运算符?无效值默认为 and
默认:and
允许值和行为
and- 所有权限都必须为 trueor- 至少有一个权限必须为 truexor- 排他或
users_model
设置在 CLI artisan 命令和 PermyModel 中使用的默认用户模型,用于描述多对多关系。
默认: App\User
godmode
当设置为 true 时,所有路由权限都返回 true。这可能对调试很有用...
默认: false
debug
当设置为 true 时,权限检查期间的所有异常都将抛出。将其视为 严格模式
默认: false
filters
一个基于过滤器的数组,Permy 根据这些过滤器构建一个权限列表以进行管理。可填充的数组表示可通过 UI 管理的过滤器。受保护的数组表示在 UI 中不可见的过滤器,这些过滤器通过 DB 或 CLI 手动管理。
默认
[
'fillable' => ['permy'],
'guarded' => []
]
本地化
OMG PLZ STAHP!
调用 getList() 方法后,您现在有了所有受限路由和控制器的语言文件。我们鼓励您编辑这些文件,以便更好地让那些管理前端应用程序的人理解。
文件位置
Laravel 4.2
app/lang/packages/{locale}/laravel-permy/permy.php
Laravel 5.0+
resources/lang/vendor/laravel-permy/{locale}/permy.php
示例文件
return array ( 'Acme::UsersController' => array ( 'name' => 'A name for the non-tech people', 'desc' => 'In case if anyone reads these, provide some sort of help for managers.', 'methods' => array ( 'myAwesomeMethod' => array ( 'name' => 'Managers may think camelCase is weird.', 'desc' => '"rm -rf ~" is not a very helpful description.', ) ) ) );
如您在最上面所述已发布翻译文件,则应在应用程序的 lang 目录中拥有 defaults.php 文件。它负责控制器和方法默认的 (duh!) 名称和描述。
当第一次创建 permy.php 文件或更新为新数据时 - 这些是每个人都不愿意更新那么多值。您可以为此文件中的每个区域设置提供翻译。
[
// :controller is replaced with the name-spaced controller name
'controller' => [
'name' => '* :controller - please update',
'desc' => '* The developer was way to busy to care describing the :controller class',
],
// :controller is replaced with the name-spaced controller name
// :method is replaced with the controller method name
'method' => [
'name' => '* :controller@:method - please update',
'desc' => '* The developer was way to busy to care describing the :method method of :controller class',
],
];
Artisan命令
HALT AND CATCH FIRE
can
permy:can <user_id> <routes> [-o|--operator [OPERATOR]] [-e|--extra_check [EXTRA_CHECK]] [-m|--model [MODEL]] [-g|--godmode [GODMODE]] [-d|--debug [DEBUG]] [-l|--roles_logic_operator [ROLES_LOGIC_OPERATOR]] [--]
模拟 Permy 公共方法,但更酷,因为它来自 CLI。以漂亮的颜色将结果打印回屏幕。
artisan permy:can 1 users.index
artisan permy:can 1 'Acme\UsersController@index'
artisan permy:can 1 'Acme\UsersController@index' -m 'Acme\OtherUser'
artisan permy:can 1 users.index,users.show
artisan permy:can 1 'Acme\UsersController@index,Acme\UsersController@show'
artisan permy:can 1 'Acme\UsersController@index,Acme\UsersController@show' -l or
更多命令即将到来
异常
RTFM - 成就解锁!
如果 debug 或 strict mode(如果你愿意)设置为 true,则可能抛出这些异常。您可以在应用程序的任何地方捕获它们。
PermyFileCreateException
创建 permy.php 语言文件时出错
PermyFileUpdateException
更新 permy.php 语言文件时出错
PermyMethodNotSetException
您尝试检查的方法未在 DB 中显式设置。当 debug 为 false 时默认为 false
PermyControllerNotSetException
您尝试检查的控制器在 DB 中不存在作为列名。当 debug 为 false 时默认为 false
PermyPermissionsNotFoundException
未能获取当前用户的权限
反馈
后端需要适当的滋养,而你却没有做任何事情!
合作、错误报告、功能和拉取请求始终欢迎!