Authorizing Resource Controllers in Laravel Post does not work?

随声附和 提交于 2020-08-20 03:11:11

问题


I have created a ProductPolicy where I have:

<?php

namespace App\Policies;

use App\Models\Product;
use App\Models\Vendor;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class ProductPolicy
{
    use HandlesAuthorization;

public function before($user, $ability){
    if($user->roles == 'admin' || $user->roles == 'editor'){
        return true;
    }
}

public function viewAny(User $user)
{
    return true;
}

public function view(User $user, Product $product)
{
    $vendor_id = Vendor::where('user_id', $user->id)->pluck('id')->first();
    return $vendor_id === $product->vendor_id;
}

public function create(User $user)
{
    return true;
}

public function update(User $user, Product $product)
{
    $vendor_id = Vendor::where('user_id', $user->id)->pluck('id')->first(); 
    return $vendor_id === $product->vendor_id;
}

public function delete(User $user, Product $product)
{
    $vendor_id = Vendor::where('user_id', $user->id)->pluck('id')->first();
    return $vendor_id === $product->vendor_id;
}

public function restore(User $user, Product $product)
{
    //
}

public function forceDelete(User $user, Product $product)
{
    //
}
}

I am allowing user to edit, update, delete the product if they owns it. According to the laravel documentation we can use authorizeResource method if we have used resource controller. That is why I added this:

$this->authorizeResource(Product::class, 'products');

in the ProductController

But when I tried to delete, edit the products own by the specific vendor, it says, 403 authorized. More importantly I am using view

@foreach($allProducts as $productLists) 
@can('view', $productLists)
      codes....
   @endcan
@endforeach

But, if I do

public function viewAny(User $user)
{
    return false;
}

instead of

public function viewAny(User $user)
{
    return true;
}

Even the admin and editor cannot add, edit, update and view the products. What is wrong going here?

Edit In my web.php I have used resource route like below:

Route::resource('products','ProductController');

回答1:


I think the issue with the type of the foreign field is coming like a string, not an integer and you are using === operator instead of ==.

So there are two possible solutions.

use == instead of == operator

or convert the string into an integer before compare

return $vendor_id === (int)$product->vendor_id;

and The authorizeResource method accepts the model's class name as its first argument but you are using the wrong name(products) it should be "product". I think it should be(remove s from products)

$this->authorizeResource(Product::class, 'product');

<?php

namespace App\Policies;

use App\Models\Product;
use App\Models\Vendor;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class ProductPolicy
{
    use HandlesAuthorization;

    public function before($user, $ability){
        if($user->roles == 'admin' || $user->roles == 'editor'){
            return true;
        }
    }

    public function viewAny(User $user)
    {
        return true;
    }

    public function view(User $user, Product $product)
    {
        $vendor_id = Vendor::where('user_id', $user->id)->pluck('id')->first();
        return $vendor_id == $product->vendor_id; // issue here
    }

    public function create(User $user)
    {
        return true;
    }

    public function update(User $user, Product $product)
    {
        $vendor_id = Vendor::where('user_id', $user->id)->pluck('id')->first(); 
        return $vendor_id === (int)$product->vendor_id; // issue here
    }

    public function delete(User $user, Product $product)
    {
        $vendor_id = Vendor::where('user_id', $user->id)->pluck('id')->first();
        return $vendor_id === (int)$product->vendor_id; // issue here
    }

    public function restore(User $user, Product $product)
    {
        //
    }

    public function forceDelete(User $user, Product $product)
    {
        //
    }
}

You can run the following statement in any policy function(where you compare the things) then you will get the idea.

echo gettype($vendor_id).", ".gettype($product->vendor_id);
die;


来源:https://stackoverflow.com/questions/63167346/authorizing-resource-controllers-in-laravel-post-does-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!