Skip to main content

Middleware: Filtering HTTP Requests

8/28
Chapter 2 Routing, Controllers, and Middleware

Middleware: Filtering HTTP Requests

18 min read Lesson 8 / 28

Middleware in Laravel

Middleware provides a mechanism for filtering HTTP requests before they reach your controller. Think of middleware as layers of an onion — each request passes through them sequentially.

Creating Middleware

php artisan make:middleware EnsureUserIsAdmin
class EnsureUserIsAdmin
{
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->user()?->role !== 'admin') {
            abort(403, 'Access denied.');
        }

        return $next($request);
    }
}

Registering Middleware

In bootstrap/app.php:

->withMiddleware(function (Middleware $middleware) {
    // Global middleware (every request)
    $middleware->append(TrackPageViews::class);

    // Alias for route-level use
    $middleware->alias([
        'admin' => EnsureUserIsAdmin::class,
        'subscribed' => EnsureUserIsSubscribed::class,
    ]);
})

Applying to Routes

Route::get('/admin', [AdminController::class, 'index'])
    ->middleware('admin');

Route::middleware(['auth', 'admin'])->group(function () {
    Route::resource('/users', UserController::class);
});

Rate Limiting

Configure rate limiting in AppServiceProvider:

public function boot(): void
{
    RateLimiter::for('api', function (Request $request) {
        return Limit::perMinute(60)->by(
            $request->user()?->id ?: $request->ip()
        );
    });

    RateLimiter::for('login', function (Request $request) {
        return Limit::perMinute(5)->by(
            $request->input('email') . $request->ip()
        );
    });
}
Route::post('/login', [AuthController::class, 'login'])
    ->middleware('throttle:login');

After Middleware

Middleware can also act on the response after the controller runs:

public function handle(Request $request, Closure $next): Response
{
    $response = $next($request);

    // Add security headers
    $response->headers->set('X-Frame-Options', 'DENY');
    $response->headers->set('X-Content-Type-Options', 'nosniff');

    return $response;
}

Middleware keeps cross-cutting concerns like authentication, rate limiting, and CORS separate from your business logic.