Laravel: On-demand authorization

Look mom, no actions!

Photo by Markus Winkler on Unsplash

The Authorization Guard of Laravel has always been a convenient way to authorize actions, and Policies mix authorization over Eloquent Models like magic.

Dealing with authorization is not always pretty, though. Unless you want to throw exceptions manually, you are forced to register an action into the Gate to be called later. It’s something counterproductive when you think about an authorization that’s is only checked once across all the application.

My most recent pull request into Laravel, which should be ready for version 8.75 any time this week, allows just that.

Quick and not dirty

Let’s say we have a controller where the user can publish an Article. The Article itself must meet only one condition to be published: it has to be approved by an editor beforehand, something that is done elsewhere in the application.

Instead of registering an action and calling the Gate, we can do this authorization in one line.

That’s it. No need to register anything or making and if statement with an exception. We can just pass a truthy condition and keep going.

We can also do the inverse with denyIf(). For example, we want to deny publishing the Article if is set as private.

Making authorization relatable

The above code makes sense for the developer, but not for the end user.

Let’s say Jimmy calls his editor to check the Article he wrote, and Mark approves right away. A couple of seconds pass, he retracts and rejects it. Jimmy doesn’t know what happend after the call, so he presses the “Publish” button anyway. The result? A page says that he doesn’t have permission to do that.

To avoid keeping Jimmy into the dark, we can add a message to the authorization exception.

In Laravel, when an authorization exception is thrown, the message will be printed on the error page by default.

Do it simple, or do it complex

There are few scenarios where you will want to make a check over the authenticated user. You don’t need to register an action into the Gate, but instead, you can pass a callback that receives an user instance.

For example, we want to allow publishing if the current user authenticated is an administrator, or the Article is already approved.

We can also use the power of the authorization Response, and hijack the callback anytime, like a short circuit. Following the same example, let’s add a condition to deny the publishing if the author of the article has been banned.

Any callback will fail automatically if the user is not authenticated, even if the user as parameter is not set in the callback, by returning an AuthorizationException.

To avoid that, we can allow guests by explicitly setting the $user variable to null. For example, we can do that for comments: any guest can comment an Article with a word-count restriction, but a banned user won’t be able to.

Of course the above is only the tip of the iceberg. For package maintainers, this means they can authorize actions without needing to register actions or throw an AuthorizationException manually.

For users, one-line authorization is now possible without having to set up the kitchen sink.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Italo Baeza Cabrera

Italo Baeza Cabrera


Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor.