lbausch/laravel-fortress

Laravel 授权的角色的权限

v0.4.1 2018-10-31 10:50 UTC

This package is auto-updated.

Last update: 2024-09-22 04:45:44 UTC


README

Laravel 授权的角色的权限

Laravel 5.1.11 已经内置了一个出色的 授权系统。Fortress 旨在以易于使用、非侵入性的方式添加角色和权限的功能。

3步轻松安装

使用 composer 安装包:

composer require lbausch/laravel-fortress

config/app.php 中添加服务提供者:

Bausch\LaravelFortress\ServiceProvider::class,

发布数据库迁移和配置文件:

php artisan vendor:publish --provider="Bausch\LaravelFortress\ServiceProvider"

运行 php artisan migrate 完成安装(自动添加 Facade Fortress)。

使用 Laravel Fortress

保护您的模型

每个需要由 Fortress 保护的数据模型(如 User、Group 等)都需要实现 Contract FortressGuardContract,并且可以使用 Trait FortressGuardTrait(除了 AuthorizableContractAuthorizable)。

...
use Bausch\LaravelFortress\Contracts\FortressGuardContract;
use Bausch\LaravelFortress\Traits\FortressGuardTrait as FortressGuard;

class User extends Model implements AuthenticatableContract,
                                    AuthorizableContract,
                                    CanResetPasswordContract,
                                    FortressGuardContract
{
    use Authenticatable, Authorizable, CanResetPassword, FortressGuard;
...					

之后,模型上可以访问以下方法

  • assignRole($role_name, $resource = null):将角色(对于资源)分配给模型
  • revokeRole($role_name, $resource = null):从模型中撤销角色(对于资源)
  • hasRole($role_name, $resource = null):检查角色(对于资源)
  • hasPermission($permission_name, $resource = null):检查权限(对于资源)
  • destroyRoles():销毁模型拥有的所有角色

您还可以在模型上定义一个名为 fortress_relations() 的方法,并返回一个应该检查的额外模型(例如 Group)的 \Illuminate\Support\Collection

...
    /**
     * Fortress Relations.
     *
     * @return \Illuminate\Support\Collection
     */
    public function fortress_relations()
    {
        return $this->groups;
    }

    /**
     * Groups.
     *
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function groups()
    {
        return $this->belongsToMany(Group::class, 'group_members');
    }
...

全局角色

如您所注意到的,$resource 参数是可选的。您可以分配仅适用于特定资源的角色,或者如果省略了 $resource 参数,则分配所谓的“全局角色”。全局角色不适用于特定资源(例如文章、博客等),并在配置文件 config/laravel-fortress.php 中定义。

<?php

/*
 * Define Roles here which do not apply to a specific Resource.
 *
 * role_name => [permissions]
 */
return [
    'admin' => [
        'broadcast',
        'manageUsers',
    ],
];

全局角色可以像普通角色一样验证 - 简单地使用 can() 方法:$user->can('broadcast');。当然,$user->hasRole($global_role_name)$user->hasPermission($global_permission_name) 也可以。

策略

要为资源分配角色,您需要有一个针对资源的策略。您需要做的就是实现 FortressPolicy 所需的 fortress_roles() 方法。在 fortress_roles() 方法内部,您可以指定仅适用于策略所属资源的角色和权限。确保按照您为策略方法命名权限(例如,不要使用空格)。

...
use Bausch\LaravelFortress\Contracts\FortressPolicy;

class BlogPolicy implements FortressPolicy
{
    /**
     * Fortress Roles.
     *
     * @return array
     */
    public function fortress_roles()
    {
        return [
            'owner' => [
                'edit',
                'destroy',
            ],
        ];
    }
...

中间件

要使用提供的中间件,您需要将其添加到您的 Kernel(app/Http/Kernel.php

...
    /**
     * The application's route middleware.
     *
     * @var array
     */
    protected $routeMiddleware = [
        ...
        'role' => \Bausch\LaravelFortress\Http\Middleware\VerifyGlobalRole::class,
        'permission' => \Bausch\LaravelFortress\Http\Middleware\VerifyGlobalPermission::class,
        ...
    ];
...

以下示例(app/Http/routes.php)说明了如何使用中间件

Route::group(['middleware' => 'role:admin'], function () {
});

Route::group(['middleware' => 'permission:broadcast'], function () {
});

注意,中间件目前只能验证全局角色和权限。

检索所有允许的资源

您通常会想检索您的用户/组具有特定权限的所有资源。Fortress 可以满足您的需求

$readable_blogs = $user->myAllowedResources('read', Blog::class);

此方法将返回用户具有“读取”权限的所有博客。

重要:当涉及解析请求的资源时,myAllowedResources 方法相当有限,因为它会生成大量的查询(每个找到的资源都会生成一个)。幸运的是,你可以传递一个闭包作为第三个参数,并自己提供解析逻辑(例如,也检索某些关系)。

$readable_blogs = $user->myAllowedResources('read', Blog::class, function($resources) {
    // $resources contains a Collection of all found Resources
    return Blogs::whereIn('id', $resources->pluck('resource_id'));
});

检索具有特定权限的所有模型

如果你想找到给定资源上具有特定权限的所有模型,只需在 Fortress 门面上调用电 allowedModels() 方法。

$users_who_can_read_this_blog = \Fortress::allowedModels('read', $blog_instance');

当然,allowedModels() 也接受一个闭包作为第三个参数,允许你使用自己的解析逻辑。

如果你想使用依赖注入,请使用 \Bausch\LaravelFortress\Contracts\Fortress::class

关于删除模型的说明

Fortress 会拦截模型的删除过程。这意味着如果你从数据库中删除使用 FortressGuardTrait 的模型,所有分配的角色都会从数据库中删除。如果你的模型使用软删除功能,所有分配的角色都会保留,直到你的模型被永久删除。