【问题标题】:How to create Policies without parameters in Laravel 5.2?如何在 Laravel 5.2 中创建没有参数的策略?
【发布时间】:2016-12-08 16:11:14
【问题描述】:

我正在尝试创建一个项目来添加编辑联系人。

为了限制用户可以添加/编辑自己的联系人,所以添加了策略 ContactPolicy 如下

<?php

namespace App\Policies;

use Illuminate\Auth\Access\HandlesAuthorization;
use App\User;
use App\Contact;

class ContactPolicy
{
    use HandlesAuthorization;

    /**
     * Create a new policy instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    public function before($user, $ability)
    {
        if ($user->isAdmin == 1) {
            return true;
        }
    }

    public function add_contact(User $user)
    {
        return $user->id;
    }

    public function update_contact(User $user, Contact $contact)
    {
        return $user->id === $contact->user_id;
    }
}

并在 AuthServiceProvider 中注册如下

protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        Contact::class => ContactPolicy::class,
    ];

为了限制当前用户添加联系人,我在我的控制器函数中添加了 Gate,如下所示,没有传递参数

if (Gate::denies('add_contact')) {
            return response('Unauthorized.', 401);
        }

即使当前用户尝试添加联系人,它也会显示未经授权的消息。

我将如何解决这个问题?

【问题讨论】:

  • 该方法必须返回一个布尔值,但是您的 add_contact() 方法返回 return $user-&gt;id; 并且它可能不起作用,因为您需要一个参数 $user 从控制器调用门时不包括在内。

标签: laravel laravel-5.2


【解决方案1】:

策略旨在将与某一类资源相关的所有授权逻辑集中在一个地方。

因此,您定义了Contact::class =&gt; ContactPolicy::class,这意味着 ContactPolicy 包含有关联系人的所有策略。当你写Gate::denies('add_contact')时,框架怎么知道要搜索哪个策略?您必须将 Contact 类型的对象作为第二个参数传递才能访问 ContactPolicy。

无论如何,实际上有一个地方可以编写授权逻辑,它不是特定于任何资源类别的。在AuthServiceProvider 的方法boot 中,您可以添加

 $gate->define('add_contact', function ($user) {
        return $user->id;
 });

顺便问一下,返回用户ID的目的是什么?我认为你只需要返回一个布尔值。

另外,如果您正在检查控制器内的权限,您应该调用$this-&gt;authorize('add_contact'),如果失败,控制器本身将检查并返回一个禁止响应(正确的代码是 403,而不是 401),否需要自己退货。

【讨论】:

    猜你喜欢
    • 2016-09-11
    • 2016-07-24
    • 1970-01-01
    • 2019-06-11
    • 2016-08-27
    • 2016-07-19
    • 1970-01-01
    • 2017-04-01
    • 2023-03-06
    相关资源
    最近更新 更多