【问题标题】:Laravel policy not workingLaravel 政策不起作用
【发布时间】:2018-07-23 13:33:41
【问题描述】:

在我的 Laravel 应用程序中,我有几个有效的策略,但一个不起作用。

控制器

    public function store(Project $project, CreateActionRequest $request)
{
    $this->authorize('store',  $project);

    Action::create([
        'name' => $request->name,
    ]);

    return redirect()->route('projects.show', $project->id)->withSuccess('Massnahme erfolgreich gespeichert');
}

政策

namespace App\Policies\Project;
use App\Models\Project\Project;
use App\Models\User;
use App\Models\Project\Action;
use Illuminate\Auth\Access\HandlesAuthorization;
class ActionPolicy
{
use HandlesAuthorization;

public function store(User $user, Project $project)
{
    return $user->company_id === $project->company_id;
}
}

AuthServiceProvider

    protected $policies = [
    'App\Models\User' => 'App\Policies\CompanyAdmin\UserPolicy',
    'App\Models\Company' => 'App\Policies\CompanyAdmin\CompanyPolicy',
    'App\Models\Team' => 'App\Policies\CompanyAdmin\TeamPolicy',
    'App\Models\Department' => 'App\Policies\CompanyAdmin\DepartmentPolicy',
    'App\Models\Location' => 'App\Policies\CompanyAdmin\LocationPolicy',
    'App\Models\Division' => 'App\Policies\CompanyAdmin\DivisionPolicy',
    'App\Models\Costcenter' => 'App\Policies\CompanyAdmin\CostcenterPolicy',
    'App\Models\Workplace' => 'App\Policies\CompanyAdmin\WorkplacePolicy',
    'App\Models\Product' => 'App\Policies\CompanyAdmin\ProductPolicy',
    'App\Models\Project\Action' => 'App\Policies\Project\ActionPolicy',
    'App\Models\Project\Project' => 'App\Policies\Project\ProjectPolicy',
];

创建动作请求

namespace App\Http\Requests\Project;

use Illuminate\Foundation\Http\FormRequest;

class CreateActionRequest extends FormRequest
{

public function authorize()
{
    return true;
}


public function rules()
{
    return [
        'name' => 'required|min:3',
    ];
}
}

除 ActionPolicy 和 ProjectPolicy 外,所有策略均有效。 我在策略中添加了一个 __construct() 方法来检查是否调用了策略。但是 ActionPolicy 和 ProjectPolicy 不起作用。 我如何搜索错误?我尝试使用 dd() 但我始终只收到消息:此操作未经授权

【问题讨论】:

  • 向我们展示来自CreateActionRequest的代码
  • 您的CreateActionRequest 看起来不错,即使您没有在内部使用Action Policy,因为您正在返回true,就好像用户总是被授权一样,所以问题不在于您的CreateActionRequest,您需要在某些 pastebin 上发布来自 laravel.log 的错误堆栈跟踪,然后使用链接更新您的问题
  • @NikolaGavric:laravel.log 中没有关于此错误的消息。
  • 问题不在于您的CreateActionRequest 也不在于您的Action Policy 从我所看到的,您能否确认您发送的name 属性在您的@987654336 中至少包含3 个字母@并确认这是您获得unauthorized的方法?
  • 如果我禁用$this->authorize('store', $project);,则输入将毫无问题地存储。表单中的字段:pastebin.com/raw/2kyD40Qn

标签: laravel policy


【解决方案1】:

由于您注入的是CreateActionRequest 而不是Request,这意味着您正在定义自己的一组规则来授权您方法中的FormRequest。此外,这意味着您必须定义一些规则,“FormRequest”必须通过这些规则才能到达您的控制器,这是一个不错的概念,我喜欢 Laravel,因为代码不是集中式的,而是分散式的,每个层有它自己的责任。现在,您不必从您的 CreateActionRequest 调用任何方法,也不必在控制器中编写有关该类的任何代码,因为 Laravel 在允许 default 运行 authorize 方法之前允许 Request 到达您的控制器,在您的 CreateActionRequest 中运行 authorizemethod 之前,它会运行 rules 方法,该方法验证所有给定字段是否都传递了您分配给它们的表达式,因此执行类似于 CreateActionRequest => rules => authorize => IF(authorized) Controller ELSE Not authorized,希望这是有道理的。为了修复您的代码:

1.) 删除$this->authorize('store', $project);

这将允许您通过not authorized 错误,以防您的name 通过rules 内部CreateActionRequest 方法内部的真值测试。如果您想使用您的 Action Policy,您需要将您的自定义 Request(CreateActionRequest) 与它挂钩,方法如下:

public function authorize()
{
    $store = $this->route('project');
    //The above line will return Project object if your mapping is correct
    //If it's not it will return the value you passed to your route for {project}
    return $this->user() && $this->user()->can('store', $store);
}

编辑:

Here is the link 在这里您可以看到如何正确授权和连接策略与CreateActionRequest

【讨论】:

  • 不幸的是仍然无法正常工作。对我来说奇怪的是,我在同一个应用程序中有 10 个具有相同概念的模型。他们工作得很好。所以我将从头开始创建一个新模型并检查是否有不同之处。
  • 从控制器中删除 $this->authorize 时会出现同样的错误?
  • 当我只删除$this->authorize它时效果很好。我所看到的,在我展示的过程中,调试栏门是空的。但是使用您的解决方案,它会返回很多信息(项目)但结果仍然是错误的。
  • 好吧,从控制器中删除 $this->authorize 并且不更改 CreateActionRequestauthorize 方法的代码,您将获得授权,但请再次阅读我的答案并查找 authorizing form requests 我已经放了一个我的答案中的链接将帮助您正确implement您的policy
  • 感谢您的帮助。现在它正在工作。但我必须在 ProjectPolicy 中设置规则,而不是在 ActionPolicy 中。但我还是不明白,为什么其他模型都正常工作!
【解决方案2】:

您是否最后使用Request 对象定义了所有控制器方法?

public function store(Project $project, CreateActionRequest $request)

Request 对象应该是方法签名中的第一个参数:

public function store(CreateActionRequest $request, Project $project)

依赖注入和路由参数

如果您的控制器方法也需要路由参数的输入,您应该在其他依赖项之后列出您的路由参数。

大多数 Laravel 授权机制具有相同的方法签名,允许它们跨不同的类工作。

【讨论】:

  • 不,只有这个顺序错误。我改了,结果还是一样。
猜你喜欢
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
  • 2015-06-03
  • 1970-01-01
  • 2020-09-27
相关资源
最近更新 更多