laravellaravel-5authorizationpolicylaravel-5.8

Custom message on Laravel policy authorization


In my Laravel 5.8 project I am implementing a reputation system similar to Stack Exchange's one: for example, users can reply to a discussion only if they have "Level 3" reputation.

I wanted to use Laravel's policies system to build the permissions logic like so in my DiscussionPolicy file:

public function reply(User $user)
{
    $result = true;
    if ($user->current_level < 3) {
        $result = false;
        //I want to inject a custom error message here
    }
    return $result;
}

Everything works, but users get a 403 page without any explanation, and I wanted to find an elegant way to tell them that they cannot perform that action because they don't have Level 3.

Can you please suggest a way to inject somehow this message, to show it in my custom 403.blade.php page? I've been able to do this by flashing a variable in the session, but I don't think it's elegant, I would like to use something like a MessageBag (Illuminate\Support\MessageBag).

LARAVEL 8.x : check this answer.


Solution

  • Answer was given in comments, put here for reference:

    Laravel provides this functionality through the deny() function in the HandlesAuthorization trait. The deny() function throws an UnauthorizedException but allows you to specify a message instead of throwing a plain exception.

    Replace the return false with it and you can send custom messages to render in the exception handler.

    Example:

    public function reply(User $user)
    {
        if ($user->current_level < 3) {
            $this->deny('Sorry, your level is not high enough to do that!');
            // Laravel 6+ requires you to return the deny(), see following line
            // return $this->deny('Sorry, your level is not high enough to do that!');
        }
        return true;
    }