在 Backpack 中,调用 authorize() 的合适位置在哪里?

In Backpack, where is the appropriate place to put the authorize() call?

Backpack 控制器不包含 Laravel 典型的 Rest 方法,但使用特征来实现 CRUD 操作,偶尔(但不总是 - 例如删除不)设置方法(setupListOperation 例如)。

对于授权,对于我的应用程序的其余部分,我在 AppServiceProvider 中使用 Gate 声明,并声明 $this->authorize() 以检查我的每个控制器中的授权。

我在哪里可以使用 authorize() 检查我从 Backpack 实现的每个操作?我找不到似乎适合覆盖的方法,以便在继续之前 运行 该授权。

您通常会在 FormRequest 类 中执行此操作,请参阅 https://backpackforlaravel.com/docs/4.1/crud-tutorial#the-request

示例:

<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;
use Illuminate\Foundation\Http\FormRequest;

class TagRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // only allow updates if the user is logged in
        return backpack_auth()->check();
    }

}

然后您将请求设置为给定操作的验证器:

例子

  protected function setupCreateOperation()
  {
      $this->crud->setValidation(TagRequest::class);

      // TODO: remove setFromDb() and manually define Fields
      $this->crud->setFromDb();
  }

注意:虽然在文档或生成的控制器中不清楚(如果您使用命令行生成器),您实际上可以为所有操作设置设置方法:

如果您查看包 allin.com/vendor/backpack/crud/src/app/Http/Controllers/CrudController.php 文件,在 setupConfigurationForCurrentOperation 方法中您会发现:

/**
 * Load configurations for the current operation.
 *
 * Allow developers to insert default settings by creating a method
 * that looks like setupOperationNameOperation (aka setupXxxOperation).
 */
protected function setupConfigurationForCurrentOperation()
{
    $operationName = $this->crud->getCurrentOperation();
    $setupClassName = 'setup'.Str::studly($operationName).'Operation';
  
    //.....

    /*
     * THEN, run the corresponding setupXxxOperation if it exists.
     */
    if (method_exists($this, $setupClassName)) {
        $this->{$setupClassName}();
    }
}

这意味着如果您的控制器定义了一个 setupDeleteOperation 函数,它将在为您的 CRUD 设置 delete 路由期间被调用。

在使用@Wesley Smith 的回答后,我发现了一个 one-step 方法。

正如 Wesley 提到的,您可以为所有 crud 操作创建设置方法,这是通过身份验证的绝佳场所。但是,它不会更新其他操作的 links。例如,列表仍将包含一个 link 来“编辑”,即使它是未经授权的。您可以使用单独的行删除它们,但还有更简单的方法。

相反,您可以使用 Setup 方法传递 allow/deny 方法。这是我的 setup() 现在显示的内容。

    public function setup()
    {
        CRUD::setModel(Workshop::class);
        CRUD::setRoute(config('backpack.base.route_prefix') . '/workshop');
        CRUD::setEntityNameStrings('workshop', 'workshops');

        if (Gate::denies('admin.workshop.list'))
            $this->crud->denyAccess('list');
        if (Gate::denies('admin.workshop.show'))
            $this->crud->denyAccess('show');
        if (Gate::denies('admin.workshop.create'))
            $this->crud->denyAccess('create');
        if (Gate::denies('admin.workshop.update'))
            $this->crud->denyAccess('update');
        if (Gate::denies('admin.workshop.delete'))
            $this->crud->denyAccess('delete');
    }

这不仅会拒绝访问这些方法,还会使用适当的 @can blade 指令更新每个方法,这意味着未经授权的方法不会显示为 links。