Mrtvac's avatar

Return JSON from authorisation in FormRequest?

I'm doing authorisation and validation in Form Request.

Content is always sent as JSON and headers for Content Type/Accept are set to application/json

While validation always return error message in JSON format, authorisation part returns exception and not JSON.

Is there a way to return JSON or will I need to move authorisation from FormRequest to controller?

Hope this makes sense.

Thanks.

0 likes
14 replies
Mrtvac's avatar

For those who are wondering, I've currently resolve this by adding $exceptions->render into app.pho bootstrap.

Something like this

        $exceptions->render(function (AccessDeniedHttpException $e, Request $request) {
            if ($request->is('api/*')) {
                return response()->json([
                    'message' => 'Forbidden.',
                ], 403);
            }
        });

But was wondering if this can be done through some configuration.

tykus's avatar

The FormRequest should throw an AuthorizationException which the framework will convert to a Response with a 403 status, and respecting the Accept header, i.e. if you want JSON it will return JSON.

You can customise how an AuthorizationException is handled in the App\Exceptions\Handler class (pre-L11) or you can use the withExceptions method when bootstrapping the app in bootstrap/app.php to determine how it should be rendered by your application.

Mrtvac's avatar

@tykus Yeah, the thing is, for some reason it doesn't return JSON although I have "Accept" set to application/json in the request header....

Mrtvac's avatar

@tykus Sorry, my bad, I didn't explain myself well. It does return JSON, but it returns the Exception so my real question is, without messing with app.php in bootstrap, is there a way to convert this Exception to error message JSON object?

Mrtvac's avatar

@tykus I would expect it to be like on other JSON responses (for example when you're unauthenticated

{
	"message": "error message"
}
tykus's avatar

@Mrtvac isn't that exactly what you will get:

{
    "message": "This action is unauthorized."
}

If APP_DEBUG is true then the exception detail will also be included; not included whenever false

Mrtvac's avatar

@tykus Nope, I'm getting this:

{
    "message": "This action is unauthorized.",
    "exception": "Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException",
    "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
    "line": 631,
    "trace": []

Trace array is big and I didn't want to copy/paste it all.

tykus's avatar
tykus
Best Answer
Level 104

@Mrtvac yes, as I explained above, your message is there. The trace is included whenever debug mode is enabled. If you change the APP_DEBUG in your environment file to false; it will only have the message key

APP_ENV=local
APP_DEBUG=false
Mrtvac's avatar

@tykus Ah, yeah, almost there. :) Thank you. It's not actually APP_ENV to "production" but rather APP_DEBUG to FALSE which will work in this case.

If you have APP_ENV to production and APP_DEBUG to TRUE it will still show full track.

tykus's avatar

@mrtvac

It's not actually APP_ENV to "production" but rather APP_DEBUG to FALSE which will work in this case

I actually had exactly that scenario tested to double check my answer

APP_ENV=local
APP_DEBUG=false

but wrote the exact opposite above 🤦‍♂️ - I will update the earlier post for any future readers. If you're all set mark the thread closed.

Please or to participate in this conversation.