Articles

Laravel Authorization: Gate and Policy Ultimate Guides

Laravel Authorization

For Laravel Authorization,  you must be familiar with Gates and Policies. First, let’s have some basic definitions and then, learn how to implement these access controls in Laravel 12.

Laravel Authorization

Authorization is used to check that some user is allowed to do specific action or not. Even checking that user has access to some resources or not. In Laravel, There are two methods to manage these permissions:

  • Gates: Good for simple, closure-based authorization checks.
  • Policies: Structured classes that handle authorization for specific models.

Based on your application security and scenarios,both methods can be used to be sure users can only perform actions they’re allowed to do. Let’s check in details but make sure you have installed laravel on your system. If not, use this : Install Laravel with Composer and Laravel installer

 

Laravel Gates

Laravel Gates

Laravel Gates

Gates in laravel authorization are closures that check if a user can perform a specific action. They’re flexible, simple and easy to define.

Defining Gates

To define a gate, inside App\Providers\AppServiceProvider.php, we should add some code to boot function like this:

use Illuminate\Support\Facades\Gate;
Gate::define('access-admin-panel', function ($user) {
 return $user->is_admin;
});

This will define a gate with name ‘access-admin-panel’ that check user is admin or not. Gates can also accept additional parameters:

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

Here we defined ‘update-post’ gate that check the authenticated user is the owner of the post.

Using Gates in Controllers

You can use ‘access-admin-panel’ gate like this in controllers:

if (Gate::allows('access-admin-panel')) {
 // Access granted
} else {
 // Access denied
}

and for ‘access-admin-panel’ gate, use like this:

/**
 * Update the given post. 
 */ 
public function update(Request $request, Post $post): RedirectResponse
{
 if (! Gate::allows('update-post', $post)) { 
    abort(403);
}

 // Update the post... 

return redirect('/posts');
}

Using Gates In Blade templates

To use gates in blade templates, you can use ‘@can’ and ‘@endcan’ tags like this:

@can('access-admin-panel')
    <a href="/admin">Admin Panel</a>
@endcan

Using Gates In Routes

To use gates in route, you can use like this:

Route::put('/post/{post}', function (Post $post) {
    // Update post
})->middleware('can:update-post,post');

 

Laravel Policy

Laravel Policy

Laravel Policies

Policies in laravel authorization are structured classes that encapsulate authorization logic for a specific model. They’re ideal for applications with complex permission requirements.

Creating Policy

Let’s suppose we have models with name ‘Post’ and ‘User’. Now to create a policy for ‘Post’ model use this:

php artisan make:policy PostPolicy --model=Post

This command creates a PostPolicy class associated with the Post model. The generated policy will be placed in the app/Policies directory.

Registering Policy

Laravel will automatically detect our policies and match it with it’s model if you use model name and Policy suffix like above. But if you use different name, you must manually register policies and their corresponding models within the boot method of your application’s AppServiceProvider like this:

use App\Models\Post; 
use App\Policies\PostPolicy; 
use Illuminate\Support\Facades\Gate; 

/** 
 * Bootstrap any application services. 
 */ 
public function boot(): void { 
  Gate::policy(Post::class, PostPolicy::class); 
}

Or you can define $policies array and add a mapping between the model class and the policy class:

protected $policies = [ Post::class => PostPolicy::class, ];

Defining Policy Methods

Inside PostPolicy.php , we can define methods like :

  • view
  • viewAny
  • create
  • update
  • delete
  • restore
  • forceDelete

For example:

<?php 

namespace App\Policies;

use App\Models\Post;
use App\Models\User;
 
class PostPolicy { 
   public function update(User $user, Post $post): bool 
   { 
      return $user->id === $post->user_id;
   }
}

This update method will check that the given post can be updated by the user or not.

Using Policy In Controller

To use this policy in controller, use authorize like this:

public function update(Request $request, Post $post) 
{ 
    $this->authorize('update', $post); // Check if user can update the post or not
    //... update logic ... 
} 

Using Policy In Blade Templates

To use this policy in blade templates, use like this:

@can('update', $post)
    <a href="{{ route('posts.edit', $post) }}">Edit</a> 
@endcan 

This will display the edit link only if the user is authorized to update the post.

Using Policy In Routes

Use the middleware(‘can:action,model’) method in your route definition like this:

Route::put('/posts/{post}', [PostController::class, 'update'])->middleware('can:update,post');

 

Gates vs. Policies: When to Use?

Feature Gates Policies
Definition Closures in AppServiceProvider Dedicated classes per model

Use Case

Simple, one-off checks Complex, model-specific permissions
Structure Less structured Highly organized and scalable
Flexibility Quick to implement Better for large applications

In laravel, It’s better to choose Gates for straightforward authorization checks and Policies when dealing with model-specific permissions that require a structured approach.

Install Laravel with Composer and Laravel installer
How to Install Composer: Step-by-Step for All Platforms
Leave a Reply

Your email address will not be published. Required fields are marked *

Shopping cart
Sign in

No account yet?

Create an Account