Laravel Middleware: Global vs Route Middleware & Pipelines

Middleware provides a convenient, modular mechanism for inspecting and filtering HTTP requests entering your application. For example, Laravel includes built-in middleware that verifies the user is authenticated, ensures CSRF tokens match, checks whether the application is in maintenance mode, and trims trailing whitespace from input fields.

Laravel Middleware Onion Pipeline Architecture

Figure 12.1: The Onion Architecture — Requests Passing Inward Through Middleware Layers

1. Generating Custom Middleware via Artisan

To create a new middleware that restricts access strictly to administrators, run:

php artisan make:middleware EnsureUserIsAdmin

Open the newly created class in app/Http/Middleware/EnsureUserIsAdmin.php:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureUserIsAdmin
{
    /**
     * Handle an incoming request.
     */
    public function handle(Request $request, Closure $next): Response
    {
        // Check if user is logged in AND possesses admin privileges
        if (!$request->user() || !$request->user()->is_admin) {
            // Abort with HTTP 403 Forbidden
            abort(403, 'Unauthorized access: Administrator credentials required.');
        }

        // Pass request inward to the next middleware or controller
        return $next($request);
    }
}

2. Registering Middleware in Laravel 11 (bootstrap/app.php)

In Laravel 11, register your custom middleware aliases or prepend/append to global pipelines inside bootstrap/app.php:

use App\Http\Middleware\EnsureUserIsAdmin;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
    )
    ->withMiddleware(function ($middleware) {
        // Register route alias
        $middleware->alias([
            'admin' => EnsureUserIsAdmin::class,
        ]);
        
        // Append to global web stack if desired:
        // $middleware->web(append: [CustomTrackingMiddleware::class]);
    })->create();

Now you can attach the admin middleware to any route or route group in routes/web.php:

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

3. "Before" vs "After" vs "Terminable" Middleware

Depending on whether your logic runs before or after the controller executes, structure the $next($request) call accordingly:

Before Middleware

public function handle($request, Closure $next)
{
    // 1. Perform security/IP checks first
    if ($this->isIpBlocked($request->ip())) {
        abort(403);
    }
    // 2. Pass to controller
    return $next($request);
}

After Middleware

public function handle($request, Closure $next)
{
    // 1. Execute controller first
    $response = $next($request);
    // 2. Modify outgoing headers
    $response->header('X-Frame-Options', 'DENY');
    return $response;
}

Terminable Middleware (terminate method)

If your middleware defines a public function terminate($request, $response) method, Laravel automatically invokes it after the HTTP response has already been sent to the user's browser. This is perfect for writing analytics to databases or dispatching non-critical log tasks without slowing down the user's page load!

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. What happens if a middleware does not call $next($request)?

If $next($request) is never called, the request pipeline is halted immediately. No further middleware or controllers will execute, and whatever response the middleware returns (or abort exception) is sent to the browser.

Q2. Can I pass parameters to middleware in my route files?

Yes! In your route definition, separate parameters with colons: Route::get('/profile', ...)->middleware('role:editor,admin'). In the middleware handle method, accept additional arguments: public function handle($request, Closure $next, ...$roles).

Q3. What is the difference between global middleware and route middleware?

Global middleware runs on every single HTTP request received by your application (e.g. maintenance checks, trim strings). Route middleware only executes when specifically assigned to matching routes or groups (e.g. auth, admin).

Explore Related Laravel Tutorials & Next Steps

Broaden your backend architecture, REST API design, and enterprise production engineering expertise:

Security Hardening & OWASP Best Practices

Implement security headers, CORS, and rate limiting with middleware.

User Authentication & Guard Middleware

Protect private routes with auth and verified middleware filters.

Route Groups & Middleware Assignment

Attach custom middleware pipelines to route groups and controllers.

BCA/MCA University Viva Questions

Explain the Onion Architecture and $next($request) pipeline in oral exams.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!