如何在Laravel 5.2中创建不带参数的策略?

时间:2016-08-03 05:30:05

标签: laravel laravel-5.2

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

要限制用户可以添加/编辑自己的联系人,请添加以下政策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);
        }

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

我将如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

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

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

无论如何,事实上有一个写授权逻辑的地方,这对任何一类资源都不是特定的。在boot的{​​{1}}方法中,您可以添加

AuthServiceProvider

顺便说一句,返回用户ID的意图是什么?我想你只需要返回一个布尔值。

此外,如果您正在检查控制器内的权限,您应该只调用 $gate->define('add_contact', function ($user) { return $user->id; }); 并且控制器本身将检查并返回Forbidden响应(正确的代码为403,而不是401)如果失败,不需要自己退货。