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.