An Introduction to Laravel Authorization Gates

Laravel Gate has an elegant mechanism to ensure users are authorized to perform actions on resources.

Before version 5.1, developers used ACL packages such as Entrust or Sentinel along with middlewares for authorization.
The problem with this approach is the permissions you attach to users are just flags; they don’t encode the complex logic of the permission for some use cases. We have to write the actual access logic within controllers.

Gate avoids some drawbacks of using just these mentioned packages:

Opinionated use case: Gate doesn’t define how you implement your models; it is up to you. This gives you the freedom to write all the complex specs your use case has however you like. You can even use ACL packages with Laravel Gate.Defining logic(policy): Using Gate we can decouple access logic from business logic, which helps remove the clutter from controllers.

A Usage Example

In this post, we’ll make a toy posts app to show how Gate gives you liberty and decoupling.
The web app will have two user roles (authors and editors) with the following permissions:

User and Role Models

If we execute the seed command, it will fail because we haven’t set our models yet. Let’s add fillable fields to app/Role model, and tell our model permissions is a JSON type field.
We also need to create relationships between app/Role and app/User models.

We need to make a StorePost request to validate the form data before storing posts. It’s simple; execute the following Artisan command.

php artisan make:request StorePost

Edit app/Http/Requests/StorePost.php and provide the validation we need in rules method.authorize method should always return true because we’re using Gate middlewares to do the actual access authorization.

Drafts

We only want authors to be able to create posts, but these won’t be accessible to the public until the editors publish them. Thus, we will make a page for drafts or unpublished posts which will be only accessible by authenticated users.

404

To have a clean appearance when a user tries to visit a nonexisting page, we need to make a 404 page. We need to create a new Blade file errors/404.blade.php and allow the user to go back to a proper page.

<html>
<body>
<h1>404</h1>
<a href="/">Back</a>
</body>
</html>

Conclusion

Our dummy application allows every user type to perform exactly the actions he has permission to. We’ve achieved that easily without using any third party packages. Thanks to this approach made possible by new Laravel releases, we don’t have to inherit features we don’t need from packages.

The business logic is decoupled from the access logic in our application; this makes it easier to maintain. If our ACL specs change, we probably won’t have to touch the controllers at all.

Next time I’ll make a post about using Gate with third party ACL packages.