backpack/permissionmanager

使用Backpack CRUD为Laravel 5提供的用户和权限管理界面。


README

Latest Version on Packagist Software License Style CI Total Downloads

用于spatie/laravel-permission的Admin界面。它允许管理员轻松添加/编辑/删除用户、角色和权限,使用Laravel Backpack

与一些其他包相反

  • 用户可以有多个角色;
  • 用户可以有额外的权限,除了他们在角色中拥有的权限外;

此包只是spatie/laravel-permission的用户界面。它将安装它,并允许您在代码中使用其API。有关如何在代码中使用更多信息,请参阅他们的README。

Edit a user in Backpack/PermissionManager

安全更新和重大更改

订阅Backpack通讯,以便了解有关任何安全更新、重大更改或主要功能的最新信息。我们每月发送1-2封电子邮件。

安装

  1. 此包假定您已安装Backpack for Laravel。如果您还没有安装,请先安装Backpack

  2. 在您的终端中

composer require backpack/permissionmanager
  1. 完成spatie/laravel-permission的所有安装步骤,它已作为依赖项拉取。运行其迁移。发布其配置文件。最有可能的是
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="permission-migrations"
php artisan migrate
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="permission-config"
// then, add the Spatie\Permission\Traits\HasRoles trait to your User model(s)
  1. 发布 backpack\permissionmanager 配置文件和迁移
php artisan vendor:publish --provider="Backpack\PermissionManager\PermissionManagerServiceProvider" --tag="config" --tag="migrations"

注意: 我们建议您只发布配置文件和迁移,但您也可以发布lang和routes。

  1. 运行迁移
php artisan migrate
  1. 此包假定可以使用默认的Backpack用户模型(最可能是 App\Models\User 来管理用户。如果您想使用不同的模型,请通过更改 config/backpack/permissionmanager.php 文件中的用户模型来实现。您使用的任何模型,请确保它使用了 CrudTraitHasRoles 特性。
<?php namespace App\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait; // <------------------------------- this one
use Spatie\Permission\Traits\HasRoles;// <---------------------- and this one
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use CrudTrait; // <----- this
    use HasRoles; // <------ and this

    /**
     * Your User Model content
     */
  1. [可选] 在 resources/views/vendor/backpack/ui/inc/menu_items.blade.php 中为其添加菜单项
<x-backpack::menu-dropdown title="Add-ons" icon="la la-puzzle-piece">
    <x-backpack::menu-dropdown-header title="Authentication" />
    <x-backpack::menu-dropdown-item title="Users" icon="la la-user" :link="backpack_url('user')" />
    <x-backpack::menu-dropdown-item title="Roles" icon="la la-group" :link="backpack_url('role')" />
    <x-backpack::menu-dropdown-item title="Permissions" icon="la la-key" :link="backpack_url('permission')" />
</x-backpack::menu-dropdown>
  1. [可选] 如果您想在Backpack路由中使用 @can 处理器,您可以

(7.A.) 将Backpack更改为使用默认的 web 守卫而不是其自己的守卫。在 config/backpack/base.php 中更改

    // The guard that protects the Backpack admin panel.
    // If null, the config.auth.defaults.guard value will be used.
-   'guard' => 'backpack',
+   'guard' => null,

注意

  • 当您添加新角色和权限时,数据库中保存的守卫将是 "web";

OR

(7.B.) 通过向您的 config/backpack/base.php 文件添加以下内容来为所有Backpack路由添加中间件

    // The classes for the middleware to check if the visitor is an admin
    // Can be a single class or an array of classes
    'middleware_class' => [
        App\Http\Middleware\CheckIfAdmin::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
+       Backpack\CRUD\app\Http\Middleware\UseBackpackAuthGuardInsteadOfDefaultAuthGuard::class,
    ],

为什么? spatie/laravel-permission 使用 Auth 门面通过 @can 确定权限。 Auth 门面使用在 config/auth.php 中定义的默认守卫,而不是我们的Backpack守卫。

请注意

  • 这将使 auth() 在Backpack路由上返回与 backpack_auth() 相同的内容;
  • 您只需要这样做,如果您想使用 @can;您也可以使用 @if(backpack_user()->can('read')),它做的是完全相同的事情,但100%有效;
  • 当您添加新角色和权限时,数据库中保存的守卫将是 "backpack";
  1. [可选] 在定义角色或权限后,使用 config/backpack/permissionmanager.php 中的配置文件禁止对您的角色或权限进行创建/更新。请注意,代码中通过名称引用权限和角色。如果允许管理员编辑这些字符串,并且他们进行了编辑,则您的权限和角色检查将停止工作。

自定义 UserCrudController

如果您想为此包提供的默认用户控制器添加更多字段,您可以绑定自己的控制器来覆盖此包中提供的控制器。

// in some ServiceProvider, AppServiceProvider for example

$this->app->bind(
    \Backpack\PermissionManager\app\Http\Controllers\UserCrudController::class, //this is package controller
    \App\Http\Controllers\Admin\UserCrudController::class //this should be your own controller
);

// this tells Laravel that when UserCrudController is requested, your own UserCrudController should be served.

API 使用

由于此包需要 spatie/laravel-permission,因此 API 将相同。请参考他们的 README 文件以获取完整的 API。不过,这里有一个总结:

使用权限

可以将权限授予用户

backpack_user()->givePermissionTo('edit articles');

可以从用户中撤销权限

backpack_user()->revokePermissionTo('edit articles');

您可以测试用户是否具有权限

backpack_user()->hasPermissionTo('edit articles');

保存的权限将注册到 Illuminate\Auth\Access\Gate 类。因此,您可以使用 Laravel 的默认 can 函数测试用户是否具有权限。

backpack_user()->can('edit articles');

使用角色和权限

可以将角色分配给用户

backpack_user()->assignRole('writer');

可以从用户中移除角色

backpack_user()->removeRole('writer');

您可以确定用户是否具有特定角色

backpack_user()->hasRole('writer');

您还可以确定用户是否具有给定的角色列表中的任何角色

backpack_user()->hasAnyRole(Role::all());

您还可以确定用户是否具有给定角色列表中的所有角色

backpack_user()->hasAllRoles(Role::all());

assignRole、hasRole、hasAnyRole、hasAllRoles 和 removeRole 函数可以接受字符串、数组、Role 对象或 \Illuminate\Support\Collection 对象。

可以将权限授予角色

$role->givePermissionTo('edit articles');

您可以确定角色是否具有特定权限

$role->hasPermissionTo('edit articles');

可以从角色中撤销权限

$role->revokePermissionTo('edit articles');

givePermissionTo 和 revokePermissionTo 函数可以接受字符串或 Permission 对象。

保存的权限和角色也注册到 Illuminate\Auth\Access\Gate 类。

backpack_user()->can('edit articles');

使用 blade 指令

此包还添加了 Blade 指令以验证当前登录用户是否具有给定角色列表中的所有或任何角色。

@role('writer')
    I\'m a writer!
@else
    I\'m not a writer...
@endrole
@hasrole('writer')
    I\'m a writer!
@else
    I\'m not a writer...
@endhasrole
@hasanyrole(Role::all())
    I have one or more of these roles!
@else
    I have none of these roles...
@endhasanyrole
@hasallroles(Role::all())
    I have all of these roles!
@else
    I don\'t have all of these roles
@endhasallroles

您可以使用 Laravel 的原生 @can 指令检查用户是否具有特定权限。

在 CRUD 控制器中使用权限

CRUD 控制器有方法来动态允许或拒绝访问操作。$this->crud->allowAccess() 和 $this->crud->denyAccess() 方法控制这些操作。

  • 表单的导航按钮显示为添加、编辑、删除等
  • 安全访问保护器,当没有权限时返回 403 禁止错误。

在大多数情况下,您应单独使用 access 和 permission。但如果您想将它们链接在一起,使 "权限" 给予 "访问",这里也有如何做到这一点的方法。提醒:权限可以直接分配给用户,也可以通过角色分配。

  1. 定义 CrudPermissionTrait
namespace App\Traits;

use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;

/**
 * CrudPermissionTrait: use Permissions to configure Backpack
 */
trait CrudPermissionTrait
{
    // the operations defined for CRUD controller
    public array $operations = ['list', 'show', 'create', 'update', 'delete'];


    /**
     * set CRUD access using spatie Permissions defined for logged in user
     *
     * @return void
     */
    public function setAccessUsingPermissions()
    {
        // default
        $this->crud->denyAccess($this->operations);

        // get context
        $table = CRUD::getModel()->getTable();
        $user = request()->user();

        // double check if no authenticated user
        if (!$user) {
            return; // allow nothing
        }

        // enable operations depending on permission
        foreach ([
            // permission level => [crud operations]
            'see' => ['list', 'show'], // e.g. permission 'users.see' allows to display users
            'edit' => ['list', 'show', 'create', 'update', 'delete'], // e.g. 'users.edit' permission allows all operations
        ] as $level => $operations) {
            if ($user->can("$table.$level")) {
                $this->crud->allowAccess($operations);
            }
        }
    }
}
  1. 在此示例中,在任意的 CrudController(如 UserCrudController)中使用上述 CrudPermissionTrait 特性。
namespace App\Http\Controllers\Admin;

use Backpack\PermissionManager\app\Http\Controllers\UserCrudController as BackpackUserCrudController;

class UserCrudController extends BackpackUserCrudController
{
    use \App\Traits\CrudPermissionTrait;

    public function setup()
    {
        parent::setup();
        $this->setAccessUsingPermissions();
    }
}

现在请确保路由使用正确的控制器

(3.A) 通过将包控制器绑定到您的控制器,如自定义 UserCrudController中所述

$this->app->bind(
    \Backpack\PermissionManager\app\Http\Controllers\UserCrudController::class, // package controller
    \App\Http\Controllers\Admin\UserCrudController::class // the controller using CrudPermissionTrait
);

OR

(3.B) 通过定义您自己的 routes/backpack/permissionmanager.php 文件中的路由,如覆盖功能中所述

Route::group([
    'namespace'  => 'App\Http\Controllers\Admin', // the new namespace
    'prefix'     => config('backpack.base.route_prefix', 'admin'),
    'middleware' => ['web', backpack_middleware()],
], function () {
    // the adapted controllers
    Route::crud('user', 'UserCrudController');
    // Route::crud('role', 'RoleCrudController');
});
Route::group([
    'namespace'  => '\Backpack\PermissionManager\app\Http\Controllers', // the original namespace
    'prefix'     => config('backpack.base.route_prefix', 'admin'),
    'middleware' => ['web', backpack_middleware()],
], function () {
    // to original controllers
    // not modified yet in this example
    Route::crud('permission', 'PermissionCrudController');
    Route::crud('role', 'RoleCrudController');
});

您可能希望使用 PermissionSeeder 来自动将权限填充到 code 中对应的 permission 表。以下是一个示例

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\Seeder;
use Backpack\PermissionManager\app\Models\Permission;
use Backpack\PermissionManager\app\Models\Role;

class PermissionSeeder extends Seeder
{
    /**
     * Run the database Permission seed.

     * Permissions are fixed in code and are seeded here.
     * use 'php artisan db:seed --class=PermissionSeeder --force' in production
     *
     * @return void
     */
    public function run()
    {
        // create permission for each combination of table.level
        collect([ // tables
            'users',
            'roles',
        ])
            ->crossJoin([ // levels
                'see',
                'edit',
            ])
            ->each(
                fn (array $item) => Permission::firstOrCreate([
                    'name' => implode('.', $item),
                ])
                    ->save()
            )
            //
        ;
        User::first()
            ->givePermissionTo(['users.edit']);
    }
}

在生产环境中使用 php artisan db:seed --class=PermissionSeeder --force

从3.x升级到4.x

从PermissionManager 3.x升级到4.x

  • 升级到spatie/laravel-permission 2.28.2+ - 请注意,数据库已更改,他们没有提供更改记录;
  • 在您的composer.json文件中要求backpack/permissionmanager版本4.0.*
  • 删除您的旧的config/backpack/permissionmanager.php文件;
  • 按照上述安装步骤操作;

如果您正在升级到Laravel 8安装,请注意,User模型可能已从App\User::class移动到App\Models\User::class,请检查您的配置是否与该更改一致config/backpack/permissionmanager.php

变更日志

有关最近更改的更多信息,请参阅CHANGELOG

覆盖功能

如果您需要修改项目中该功能的工作方式

  • 创建一个routes/backpack/permissionmanager.php文件;包将看到这一点,并加载您的路由文件,而不是包中的路由文件;
  • 创建扩展包中那些的控制器/模型,并在您的新路由文件中使用它们;
  • 修改您想在新控制器/模型中修改的任何内容;

在创建自己的控制器、seeder时,请确保您使用的是BackpackUser模型,而不是您应用程序中的User模型。最简单的方法是使用config('backpack.base.user_model_fqn'),它将完全限定的User模型命名空间引入,如您的config/backpack/base.php中定义。您可能需要使用$model = config('backpack.base.user_model_fqn'); $model = new $model;来实例化它,以便执行类似$model->where(...)的操作。

贡献

有关详细信息,请参阅CONTRIBUTING

安全性

如果您发现任何与安全相关的问题,请通过电子邮件tabacitu@backpackforlaravel.com报告,而不是使用问题跟踪器。

订阅Backpack通讯,以便了解有关任何安全更新、重大更改或主要功能的最新信息。我们每月发送1-2封电子邮件。

鸣谢

许可证

Backpack免费供非商业使用,商业使用49 EUR/项目。请参阅许可证文件backpackforlaravel.com以获取更多信息。

雇佣我们

我们投入了超过50,000小时来创建、抛光和维护Laravel的管理面板。我们开发了电子商务、电子学习、ERP、社交网络、支付网关等等。我们在管理面板上工作得如此之多,以至于我们创建了该领域最受欢迎的软件之一——只是从使我们在项目中重复的内容公开。

如果您正在寻找一个开发者/团队来帮助您在Laravel上构建管理面板,请不必再寻找。您将很难找到比这更有经验且对此充满热情的人。这就是我们所做的工作联系我们。让我们看看我们是否可以合作。