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.
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;
});
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']);
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);
}
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();
}