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:
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class AuthController extends Controller
{
use AuthorizesRequests;
public function update(Post $post)
{
$this->authorize('update-post', $post);
// User is authorized
$post->update(request()->all());
}
}
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'));
});