Laravel Middleware
Laravel middleware is code that runs before or after a request reaches your controller. It acts like a series of filters: checking login, verifying CSRF tokens, setting the language or blocking users who are not admins.
Built-in Middleware You Will Use
- auth: only logged-in users may continue
- guest: only guests (for login and register pages)
- verified: user must have verified their email
- throttle:60,1: rate limit to 60 requests per minute
- can:update,post: authorization using a policy
- signed: the URL must have a valid signature
Creating Custom Middleware
Calling $next($request) passes the request further down the chain. Anything after it runs on the way out, which is where you can modify the response.
php artisan make:middleware EnsureUserIsAdmin
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserIsAdmin
{
public function handle(Request $request, Closure $next): Response
{
if (! $request->user()?->is_admin) {
abort(403, 'Admins only.');
}
return $next($request);
}
}Non-admin -> 403 Admins only. Admin -> request continues to the controller
Registering Middleware in Laravel 11
In Laravel 11 you register middleware in bootstrap/app.php: give it an alias for routes, or append it to the web or api group to run on every request.
<?php
->withMiddleware(function (Middleware $middleware) {
$middleware->alias([
'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class,
]);
$middleware->web(append: [
\App\Http\Middleware\SetLocale::class,
]);
})(Alias "admin" now usable in routes; SetLocale runs on every web request)
Applying Middleware to Routes
<?php
Route::get('/admin', AdminDashboardController::class)
->middleware(['auth', 'admin']);
Route::middleware('auth')->group(function () {
Route::resource('posts', PostController::class);
});
Route::post('/login', LoginController::class)->middleware('throttle:5,1');GET /admin as guest -> redirect /login 6th login attempt in a minute -> 429 Too Many Requests
Middleware With Parameters
Extra arguments after a colon are passed to handle().
<?php
public function handle(Request $request, Closure $next, string $role): Response
{
abort_unless($request->user()?->role === $role, 403);
return $next($request);
}
// Route::get('/reports', ...)->middleware('role:manager');User with role "manager" -> allowed; others -> 403
Frequently asked questions
Where do I register middleware in Laravel 11?
In bootstrap/app.php inside withMiddleware(). The old app/Http/Kernel.php file no longer exists in new Laravel 11 projects.
What is the difference between middleware and policies?
Middleware filters whole requests, for example requiring login. Policies decide whether a user can perform an action on a specific model, like editing a particular post.
Can middleware modify the response?
Yes. Store $response = $next($request), change headers or content, then return it.