Laravel Basic
Laravel Form
Laravel Database
Laravel Advance
A Gate in Laravel is a simple way to authorize user actions.
It defines permissions (yes/no checks) for specific actions, usually based on user roles or conditions.
👉 Example:
Gates are not tied to models directly (that’s for Policies). Instead, they are general closures or class methods for access control.
✅ Simple Authorization → For small apps where you don’t need full Policies.
✅ Centralized Logic → Define permission rules in one place.
✅ Reusable → Apply to routes, controllers, or Blade templates.
✅ Flexible → Works with roles, permissions, or custom logic.
App\Providers\AuthServiceProvider
.AuthServiceProvider
or define inside separate service providers.php artisan make:provider AuthServiceProvider
namespace App\Providers; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Support\Facades\Gate; use App\Models\Post; use App\Models\User; class AuthServiceProvider extends ServiceProvider { public function boot(): void { Gate::define('edit-post', function (User $user, Post $post) { return $user->id === $post->user_id; }); Gate::define('is-admin', fn(User $user) => $user->role === 'admin'); } }
use Illuminate\Support\Facades\Gate; Gate::define('is-admin', function ($user) { return $user->role === 'admin'; });
use Illuminate\Support\Facades\Gate; Gate::define('update-post', function ($user, $post) { return $user->id === $post->user_id; });
You can check Gate permissions in multiple places.
use Illuminate\Support\Facades\Gate; public function update(Post $post) { if (Gate::denies('update-post', $post)) { abort(403, 'Unauthorized'); } // User is authorized $post->update(request()->all()); }
Or shortcut:
$this->authorize('update-post', $post);
Route::get('/admin', function () { return "Admin Panel"; })->middleware('can:is-admin');
@can('update-post', $post) <a href="/post/{{ $post->id }}/edit">Edit Post</a> @endcan @cannot('update-post', $post) <p>You cannot edit this post</p> @endcannot
Instead of just returning true/false
, you can return a response with a message:
use Illuminate\Support\Facades\Gate; if (Gate::any(['update-post', 'delete-post'], $post)) { // user can update OR delete } if (Gate::none(['update-post', 'delete-post'], $post)) { // user can neither update nor delete }
Sometimes, you want a super-admin to bypass all gates.
use Illuminate\Support\Facades\Gate; Gate::before(function ($user, $ability) { if ($user->role === 'super-admin') { return true; // bypass all } });
Or check after normal evaluation:
use Illuminate\Support\Facades\Gate; Gate::after(function ($user, $ability, $result) { // Log authorization attempt \Log::info("Gate check: $ability for user {$user->id} = " . ($result ? 'Allowed' : 'Denied')); });