Home > database >  How can I change Laravel Policy response status code?
How can I change Laravel Policy response status code?

Time:06-13

I'm using Laravel 9

I want to prevent User to view another User personal information. This is my Policy method

public function viewUser(User $user, User $model)
{
    return $user->id === $model->id;
}

and this is Controller method

public function show(User $user)
{
    $this->authorize('viewUser', $user);
    return view('users.show', compact('user'));
}

It shows 403 as expected

But I want to change status code to 404 like this

public function viewUser(User $user, User $model)
{
    return $user->id === $model->id
            ? Response::allow()
            : Response::deny(code: 404);
}

And it's still shows 403 not 404. What am I doing wrong with the Policy? I know I can change response using another approach but my question about Laravel Policies itself.

Route

Route::group([
    'middleware' => ['auth'],
    'prefix' => 'users/{user}',
    'as' => 'users.',
], function () {
    Route::get('/', [UserController::class, 'show'])->name('show');
});

CodePudding user response:

In app\Exceptions\Handler.php in the render() method you can define what should be done when X Exception is thrown. That being said, adding below piece of code should do the trick for you:

if ($exception instanceof AuthorizationException) {
    $exception = new NotFoundHttpException;
}

return parent::render($request, $exception);

What it does is basically checking if the Exception that is thrown is an AuthorizationException (which policies in Laravel throw) and if that is the case, throw a new NotFoundHttpException (404). This will however change any and all AuthorizationExceptions to a 404, which is probably not wanted behaviour.


Update:

After digging I found a closed proposal for returning 404.

Personally I feel that a policy should not return anything but a 403 status code, since that is the correct code, something is forbidden. Returning a 404 would not be correct since the policy does not handle X resource not found.

If you'd really want you could change the Handler.php. I feel like this is not the correct way to use policies however, but that's beside the point.

A user in above mentioned closed proposel used request parameters to check if the route belonged to a certain type, i.e. product and returned a 404 instead of 403. Maybe this can be applied to your use case aswell, check it out here. Hope I've been thorough and it maybe helps.

  • Related