问题
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