What is the Laravel authorization gate?

Authorization is a very important feature of modern web applications, and Laravel, as a progressive framework, makes the process very easy.

Laravel provides simple ways to authorize users. Gates are a simple way to authorize user actions that make it easy to check if a user is permitted to perform an action.

Defining authorization rules

Gates are defined in the boot method of the AuthServiceProvider class. A gate is created using the Gate facade.

When a gate is defined, it needs a key or name. This name should be a short description of the action. For example, to define a rule to check if a user can delete a post, the name should be delete-post.

The name should adhere to the convention of action-resource. The action could be something like create, update, or delete. The resource could just be the model name.

After the name, the gate needs a closure. The first parameter of this closure is the authenticated user, $user. The following parameters are resources that must be checked to see if the user has access. This closure returns true if the user does have access, and false otherwise.

The code snippet below creates a gate that lets a user delete a post only if it was created by them:

Gate::define('delete-post', function (User $user, Post $post) {
    return $user->id == $post->user_id;
});

Defining gates with class methods

If you have more than one gate in your application, you can create a class to contain all these methods. For example, you could create a class to contain all the rules guarding the Post resource. This class could have methods like updatePost to check if the user owns the post to be updated, deletePost to check if the user can delete the current post, etc.

These methods can be accessed when defining the gate as shown below:

Gate::define('update-post', [PostRules::class, 'updatePost']);

Using authorization rules

The easiest way to use authorization rules is to use the Gate facade. This facade exposes the allows and denies methods, to check if the user can perform the action or not. These methods return Boolean values just like in the gate definition.

The example below checks if a user can delete a post:

$post = Post::find(7);

if (Gate::allows('delete-post', $post)) {
    $post->delete();
} else {
    abort(403);
}

In this example, if the user has the correct permission, the post is deleted. If that is not the case, an authorization error is thrown.

This same feature can be achieved using the denies method in place of the allows, like this:

if (!Gate::denies('delete-post', $post)) {
    $post->delete();
} else {
    abort(403);
}

Checking if another user has permission

Other times, you want to check if a user not currently logged in has permission to a resource. To do this, you can use the forUser method on the Gate facade. This method takes in a user object and performs the check.

For example, to see if the most recently registered user can delete a post, you can use the following code:

$post = Post::find(7);
$user = User::latest()->first();

if (Gate::forUser($user)->denies('delete-post', $post)) {
    $post->delete();
}