michaeltintiuc/laravel-permy

基于定义的路由的Laravel用户权限(角色或组)。

v0.2.1 2018-08-12 13:24 UTC

README

简称“永久朋友”——我妈说我这么做挺酷的!

为您的所有Laravel应用程序提供强大且灵活的ACL;支持4.2版本及以上

  • 将单个或多个权限分配给用户,并通过ANDORXOR运算符控制继承逻辑
  • 使用多个用户模型
  • 通过支持本地化的UI或数据库管理权限
  • 通过过滤器/中间件直接在路由、路由组或控制器上设置权限
  • 使用额外的逻辑运算符进行批处理权限检查
  • Artisan命令和调试助手

待办事项

  • 类重构和抽象化
  • 为Artisan命令添加对数组权限的运算符键支持
  • 额外的辅助Artisan命令
  • 添加PHP7类型提示
  • 改进数据库访问,最小化查询次数
  • 添加Blade指令

内容

唯一一个没有滑稽注释的部分

  1. 安装
  2. 发布
  3. 数据库
  4. 使用方法
  5. 配置
  6. 本地化
  7. Artisan命令
  8. 异常
  9. 反馈

安装

美丽友谊的开始(背景音乐很俗气)

通过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_tablecreate_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.25.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,它有 indexsomeMethod 方法,你可以在 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 - 所有权限都必须为 true
  • or - 至少有一个权限必须为 true
  • xor - 排他或

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 - 成就解锁!

如果 debugstrict mode(如果你愿意)设置为 true,则可能抛出这些异常。您可以在应用程序的任何地方捕获它们。

PermyFileCreateException

创建 permy.php 语言文件时出错

PermyFileUpdateException

更新 permy.php 语言文件时出错

PermyMethodNotSetException

您尝试检查的方法未在 DB 中显式设置。当 debug 为 false 时默认为 false

PermyControllerNotSetException

您尝试检查的控制器在 DB 中不存在作为列名。当 debug 为 false 时默认为 false

PermyPermissionsNotFoundException

未能获取当前用户的权限

反馈

后端需要适当的滋养,而你却没有做任何事情!

合作、错误报告、功能和拉取请求始终欢迎!