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
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 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.