phplaravellaravel-permission

Customizing Spatie Laravel-Permission Exception Message


I have added the Saptie Laravel Permission Package in a Laravel 5.8 API application. Every works fine and I get exception when a non admin user tries to access admin specific routes.

However the default exception is rendered as HTML 403 User does not have the right roles. Considering I am using this inside an API application, I would like to return my own custom message for such exceptions.

I tried checking if the auth()->user()->hasRole('admin') but still got the same default exception page. Here's my code

route

Route::post('products', 'ProductController@store')->middleware('role:super-admin|admin'); // create a new product

Controller method

if (auth()->user()->hasRole('admin')) {

    // create & store the product
    $product = Product::create($request->all())

    // return new product
    $responseMessage    = 'Successful operation';
    $responseStatus     = 200;
    $productResource    = new ProductResource($product);

    return response()->json([
        'responseMessage'   => $responseMessage,
        'responseStatus'    => $responseStatus,
        'product'           => $productResource
    ]);
} else {

    return response()->json([
        'responseMessage'   => 'You do not have required authorization.',
        'responseStatus'    => 403,
    ]);
}

Why is my custom message not showing?


Solution

  • Because you are protecting your routes through the role middleware the UnauthorizedException will be thrown before your controller code is ever reached.

    What you can do is use laravels exception handler render method and check the exception type and return your own response:

    from the docs:

    The render method is responsible for converting a given exception into an HTTP response that should be sent back to the browser. By default, the exception is passed to the base class which generates a response for you. However, you are free to check the exception type or return your own custom response

    app/Exceptions/Handler.php

    use Spatie\Permission\Exceptions\UnauthorizedException;
    
    public function render($request, Exception $exception)
    {
        if ($exception instanceof UnauthorizedException) {
            return response()->json([
                'responseMessage' => 'You do not have required authorization.',
                'responseStatus'  => 403,
            ]);
        }
    
        return parent::render($request, $exception);
    }