I've been following the Laravel Authorization docs trying to build "is the user allowed to do this" functionality by using Policies, but I can't get it to work. I keep getting This action is unauthorized and I've tried with route middleware too.
PagePolicy.php:
namespace App\Policies;
use App\Models\User;
use App\Models\Page;
use Illuminate\Auth\Access\HandlesAuthorization;
class PagePolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the page.
*
* @param App\Models\User $user
* @param App\Models\Page $page
* @return mixed
*/
public function view(User $user, Page $page)
{
return $user->id === $page->user_id;
}
/**
* Determine whether the user can create pages.
*
* @param App\Models\User $user
* @return mixed
*/
public function create(User $user)
{
}
/**
* Determine whether the user can update the page.
*
* @param App\Models\User $user
* @param App\Models\Page $page
* @return mixed
*/
public function update(User $user, Page $page)
{
//
}
/**
* Determine whether the user can delete the page.
*
* @param App\Models\User $user
* @param App\Models\Page $page
* @return mixed
*/
public function delete(User $user, Page $page)
{
//
}
}
PageController.php:
namespace App\Http\Controllers;
use Auth;
use Carbon\Carbon;
use App\Models\Page;
use App\Http\Requests\PageRequest;
class PageController extends ApiController
{
public function createNewPage(PageRequest $request)
{
$this->authorize('create', Page::class);
$request->merge([
'user_id' => Auth::id(),
'published_at' => Carbon::now(),
]);
if (Page::create($request->all())) {
return response()->json('success', 201);
}
return response()->json('error', 500);
}
}
AuthServiceProvidor.php:
namespace App\Providers;
use App\Models\Page;
use App\Policies\PagePolicy;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
Page::class => PagePolicy::class,
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
//
}
}
I managed to figure it out. I wasn't using Route Model Binding. So I added authorize() after the page call and used the $page variable instead of Page::class.
public function update(PageUpdateRequest $request, $pageSlug)
{
$page = Page::where(['user_id' => Auth::id(), 'slug' => $pageSlug])->first();
$this->authorize('update', $page);
$page->update($request->all());
return fractal()->item($page, new PageTransformer())->toArray();
}
It's not totally clear to me which action you're attempting to authorize since you've provided the call to create in the controller but only provided a policy check in place for viewing a page. Having said that, I would be sure to var_dump/dd the values you're attempting to do a type comparison of to verify they're of the same type. If anything's been explicitly cast, it may cause issues with certain database drivers that return integers as strings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With