smart-crowd/laravel-rbac

Laravel RBAC 实现。

v0.1.3 2015-10-24 11:40 UTC

This package is not auto-updated.

Last update: 2024-09-14 17:37:24 UTC


README

Laravel 5 RBAC 实现

本包受到 Yii 框架 RBAC 模块的启发

安装

  1. 运行

    composer require "smart-crowd/laravel-rbac":"dev-master"
  2. 将服务提供者和外观添加到 /config/app.php 文件中。

    'providers' => [
        ...
    
        SmartCrowd\Rbac\RbacServiceProvider::class,
    ],
    ...
    
    'aliases' => [
        ...
        
        'Rbac' => 'SmartCrowd\Rbac\Facades\Rbac'
    ]
  3. 发布包配置

    php artisan vendor:publish
  4. 在用户模型中实现 Assignable 接口。并使用 AllowedTrait

    use SmartCrowd\Rbac\Traits\AllowedTrait;
    use SmartCrowd\Rbac\Contracts\Assignable;
    
    class User extends Model implements Assignable
    {
        use AllowedTrait;
    
        /**
         * Should return array of permissions and roles names,
         * assigned to user.
         *
         * @return array Array of user assignments.
         */
        public function getAssignments()
        {
            // your implementation here
        }
        ...
    }

使用方法

  1. /Rbac/items.php 中描述你的权限

  2. 在代码中直接使用

    if (Auth::user()->allowed('article.delete', ['article' => $article])) {
        // user has access to 'somePermission.name' permission
    }
  3. 或在中间件中

    Route::delete('/articles/{article}', [
        'middleware' => 'rbac:article.delete', 
        'uses' => 'ArticlesController@delete'
    ]);

    当然,别忘了在 /Http/Kernel.php 文件中注册中间件

    protected $routeMiddleware = [
        ...
        'rbac' => 'SmartCrowd\Rbac\Middleware\RbacMiddleware',
    ];

    要使用路由参数作为模型而不是只是 ID 在业务规则中,你应在 RouteServicePrivider.php 中将其绑定

    public function boot(Router $router)
    {
        //...
        $router->model('article', '\App\Article');
    
        parent::boot($router);
    }

    将权限名称绑定到动作名称有 3 种方式

    • 中间件参数
    • 直接在 /Rbac/actions.php 文件中绑定
    • 权限命名像动作一样,例如 article.edit 对应 ArticleController@edit 动作
  4. 或在你的视图中

    @allowed('article.edit', ['article' => $article])
        <a href="{{ route('edit', ['article' => $article]) }}">edit</a>
    @else
        <span>You can not edit this article</span>
    @endallowed

    如果启用了 rbac.shortDirectives 选项,你可以使用指令的简短形式,如下所示

    @allowedArticleEdit(['article' => $article])
        {{ $some }}
    @endallowed
    
    @allowedIndex
        {{ $some }}
    @endallowed

上下文角色

在某些情况下,你可能希望拥有动态分配的角色。例如,角色 groupModerator 是动态的,因为根据当前组,当前用户可能拥有这个角色,也可能没有。在我们的术语中,这个角色被称为“上下文角色”,当前组是“角色上下文”。上下文决定将哪些附加上下文角色分配给当前用户。在我们的例子中,Group 模型应该实现 RbacContext 接口,并实现 getAssignments($user) 方法。

检查时只需发送上下文模型和其他参数即可

@allowed('group.post.delete', ['post' => $post, 'group' => $group]) // or $post->group
    post delete button
@endallowed

但为了在中间件中自动检查路由,我们通常只发送 post 而不带组

Route::delete('/post/{post}', [
    'middleware' => 'rbac:group.post.delete', 
    'uses' => 'PostController@delete'
]);

对于这种情况,你可以通过 Post 模型实现 RbacContextAccesor 接口。 getContext() 方法应返回 Group 模型。然后你只需发送 post,上下文角色将在中间件中应用

@allowed('group.post.delete', ['post' => $post])
    post delete button
@endallowed

如果你与主题一起发送上下文,则不能这样做

Route::delete('/group/{group}/post/{post}', [
    'middleware' => 'rbac:group.post.delete', 
    'uses' => 'PostController@delete'
]);