In Depth: Policy Objects

[InDepth#8] Policy Objects are incredibly powerful. Use them.

In Depth: Policy Objects

Policy Objects are a seriously underrated component in Laravel. They are so underrated that they don’t even get their own menu item in the documentation - you need look under “Security → Authorization” to even find them! Even typing “policy” or “policy objects” into the search doesn’t pop on them either… it’s upsetting…

😭😭😭

Ok, maybe it’s not that bad, but they really are seriously underrated. So I’m hoping to undo the damage by teaching you about Policy Objects.

Strap in, we’ve got a lot to cover!

What Are Policy Objects and Why Use Them?

A Policy Object is a class that organises authorisation around a specific model or resource. They allow you to store your authorisation logic in a single place, making it easy to review and change your authorisation rules without needing to find any instances throughout your application. Laravel will automatically inject the authenticated user for comparison, supports auto-discovery and filters, allows additional context, and lets you check authorisation on models, in controllers, as middleware, and even inside blade!1

You should create a Policy for each model or resource that you need to authorise user activity around, and a method for every ability you wish to authorise. Even if the authorisation logic is trivial and/or you only need a single ability for that model, it is still beneficial to create a Policy for each model. They let you separate your business logic from your authorisation, keeping your code cleaner and giving you a logical and easy to find place where all of your authorisation rules exist, making it easy to review and update as things change over time.

Since some super smart person clearly thought that giving two confusingly similar concepts, authentication and authorisation, two confusingly similar names was a brilliant idea, let’s define them both to remove the confusion:
Authentication → You are who you say you are. I.e. When you login with your credentials, you prove you are the owner of the account2.
Authorisation → You are allowed to do what you’re trying to do. I.e. Only users with edit permissions can edit a post.

Creating Policies

Since there are multiple ways to check policy authorisation depending on the situation, we’ll cover how to create and write policies first.

You create Policy Objects using the `make:policy` artisan command3:

$ php artisan make:policy --help

Description:
  Create a new policy class

Usage:
  make:policy [options] [--] <name>

Arguments:
  name                  The name of the class

Options:
  -m, --model[=MODEL]   The model that the policy applies to
  -g, --guard[=GUARD]   The guard that the policy relies on

To create a new policy for a Post model, all we need to do is this:

php artisan make:policy PostPolicy --model=Post

Laravel will create a new policy class for you: