silvanite/novatoolpermissions

Laravel Nova 权限(基于角色和权限的访问控制(ACL))


README

通过用户角色和权限添加访问控制到您的 Nova 安装。包括默认的用户和角色策略,这些可以通过您的 Nova 管理面板进行管理。

Tool Demo

此工具在内部使用 Silvanite\Brandenburg 包来管理用户角色。Brandenburg 被使用是因为它具有清晰的职责分离。

角色 定义在 数据库

权限 定义在 代码库

因此,您将看不到任何 权限 资源。角色资源将根据您代码中定义的 Gates 获取权限。

包维护

遗憾的是,我不再积极在 Laravel 生态系统工作,因此无法维护此包。如果有人想接管包的维护,请与我联系(打开一个问题或在 Twitter 上联系我)。

安装

通过 composer 安装此工具

composer require silvanite/novatoolpermissions

运行迁移以添加 Brandenburg 所需的数据库表。

php artisan migrate

按照 Brandenburg 安装说明,将 HasRoles 特性添加到您的用户模型中。

// app/User.php

use Silvanite\Brandenburg\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
    ...
}

将其加载到您的 Nova 工具中,以在您的资源中显示角色

// app/Providers/NovaServiceProvider.php

use Silvanite\NovaToolPermissions\NovaToolPermissions;

public function tools()
    {
        return [
            new NovaToolPermissions(),
        ];
    }

您可以从角色资源中分配用户到角色,但如果您想从用户资源中分配角色,您需要添加一个额外的关系...

// app/Nova/User.php

use Silvanite\NovaToolPermissions\Role;

public function fields(Request $request)
{
    return [
        ...
        BelongsToMany::make('Roles', 'roles', Role::class),
    ];
}

如果您不使用默认的 App\Nova\User 资源,您可以通过发布 `novatoolpermissions config 并设置您的用户资源模型来自定义此操作。

php artisan vendor:publish --provider="Silvanite\NovaToolPermissions\Providers\PackageServiceProvider"

移除默认的 viewNova Gate 以使用此包包含的 Gate。您需要保留 gate() 方法,只需将其清空即可。注意:Nova 总是在开发环境中允许访问。

// app/Providers/NovaServiceProvider.php

protected function gate()
{
    //
}

用法

安装后,继续创建您的第一个角色。例如,创建 管理员 并将所有权限分配给新角色。

Create/Edit Roles

最后,将管理员角色分配给您的用户账户。

Attach Role to User

Roles index with User count

注意:默认情况下,如果没有单个用户对权限有访问权限,此包允许任何人访问权限。这是为了防止您将自己锁定在功能之外。因此,定义您的具有访问所有权限的主管理员角色很重要,这意味着除非您明确授予,否则没有人可以访问。

默认权限

此包附带一组默认权限,以提供对包功能的完全访问控制。权限附带默认英文翻译,以提供更好的用户体验。您可以在应用程序的 json 翻译中替换这些翻译。

{
    "viewNova": "Access Nova",
    "viewRoles": "View Roles",
    "manageRoles": "Manage Roles",
    "assignRoles": "Assign Roles",
    "viewUsers": "View Users",
    "manageUsers": "Manage Users"
}

自定义权限

要创建自己的权限,只需在您的服务提供者中定义它们,并为您的资源/模型创建一个 策略。让我们以一个常见的 博客 示例来工作,并假设您在应用程序中有一个 博客 模型和资源。

为您的 Nova 资源创建一个 策略

为您的博客创建一个新的策略

php artisan make:policy BlogPolicy

让我们分配策略并定义我们的 Gates。

// app/Providers/AuthServiceProvider.php

use Silvanite\Brandenburg\Traits\ValidatesPermissions;

class AuthServiceProvider extends ServiceProvider
{
    use ValidatesPermissions;

    protected $policies = [
        \App\Blog::class => \App\Policies\BlogPolicy::class,
    ];

    public function boot()
    {
        collect([
            'viewBlog',
            'manageBlog',
        ])->each(function ($permission) {
            Gate::define($permission, function ($user) use ($permission) {
                if ($this->nobodyHasAccess($permission)) {
                    return true;
                }

                return $user->hasRoleWithPermission($permission);
            });
        });

        $this->registerPolicies();
    }
}

最后,根据 Nova 文档在策略中指定访问控制。

// app/Policies/BlogPolicy.php

use Illuminate\Support\Facades\Gate;

public function viewAny($user)
{
    return Gate::any(['viewBlog', 'manageBlog'], $user);
}

public function view($user, $post)
{
    return Gate::any(['viewBlog', 'manageBlog'], $user, $post);
}

public function create($user)
{
    return $user->can('manageBlog');
}

public function update($user, $post)
{
    return $user->can('manageBlog', $post);
}

public function delete($user, $post)
{
    return $user->can('manageBlog', $post);
}

public function restore($user, $post)
{
    return $user->can('manageBlog', $post);
}

public function forceDelete($user, $post)
{
    return $user->can('manageBlog', $post);
}

并将您的标签添加到翻译中,以保持一切整洁。

{
    "viewBlog": "View Blog",
    "manageBlog": "Manage Blog"
}

此示例是一个超级简单的实现。您可以在任何标准的 Laravel 应用程序中定义您的 Gates,并且可以简单地添加额外的检查来验证它们与您分配的角色和权限。

访问控制

有时您可能想要阻止一些用户访问内容,但允许其他人访问。为了实现这一点,请在您的模型上使用包含的 HasAccessControl.php 特性。

要检查用户是否有正确权限查看您的内容,可以加载 AccessControlServiceProvider 来全局注册 accessControl gate。或者,在您的模型策略上包含 AccessControlGate 特性。

在您的 Nova 资源中添加 AccessControl 字段。这将显示所有具有 canBeGivenAccess 权限的角色。为了保护内容不被访问,至少需要将一个角色赋予模型访问权限,否则资源将对所有用户开放。

public function fields(Request $request)
{
    return [
        // ...
        AccessControl::make(),
        // ...
    ]
}

支持

如果您需要任何支持,请通过 Twitter 联系我或在此存储库中打开一个问题。