What Can You Do with Laravel Middleware? (More Than You Think!)

Did you ever find yourself writing the same checks in multiple controllers? Like formatting inputs, blocking access, or tracking user a...

Karan Datwani
Karan Datwani
Share:

Did you ever find yourself writing the same checks in multiple controllers? Like formatting inputs, blocking access, or tracking user activity? It all starts feeling repetitive, right?... and it gets old fast.

That’s where middleware comes in. Think of it as a bouncer for your app—checking, modifying, or rejecting requests before they hit your controllers. Or even after a request is handled (many people don't know this). Instead of cluttering controllers with repeated logic or separating that logic in traits, middleware helps you add functionality across multiple routes in a cleaner, more maintainable way.

Why Middleware Matters

The real power of middleware isn’t just cleaner controllers—it’s when the code runs:

  • If you put checks in __construct(), the controller is already instantiated before they run.
  • With middleware, the check happens before the controller is even touched—protecting it completely.

So, when should you create custom middleware? Let’s break it down.

How to Create Middleware (Quick Guide)

Before jumping into the examples, let’s see how to create and apply middleware so you know exactly where the code goes.

1. Generate middleware:

php artisan make:middleware YourMiddlewareName

This creates a file in app/Http/Middleware/YourMiddlewareName.php where we’ll write our logic.

2. Register it inside app/Http/Kernel.php:

protected $routeMiddleware = [
    'yourMiddleware' => \App\Http\Middleware\YourMiddlewareName::class,
];

Now, we can apply it to routes like this:

Route::get('/some-route', 'SomeController@index')->middleware('yourMiddleware');

Alright, now that we know where to put the code, let’s go over when you should create middleware.

When to Create Custom Middleware (With Examples)

1️⃣ Custom Authentication Checks

Laravel’s built-in authentication is great, but sometimes you need extra checks. Maybe you want to allow only verified users or restrict access based on roles, permissions, or subscription plans.

💡 Example: Only premium users can access certain pages

public function handle(Request $request, Closure $next)
{
    if (!$request->user() || !$request->user()->is_premium) {
        return redirect('/upgrade');
    }
    return $next($request);
}

How to use it:

Route::get('/premium-content', function () {
    return view('premium');
})->middleware('checkPremiumUser');

Now, only premium users can access this page.


2️⃣ Logging Requests Automatically

Want to track incoming requests for analytics or debugging? Middleware lets you log request details without cluttering your controllers.

💡 Example: Log every visited URL with a timestamp

public function handle(Request $request, Closure $next)
{
    \Log::info('User visited: ' . $request->url());
    $request->user()?->update(['last_seen' => now()]);
    return $next($request);
}

How to use it:

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware('trackActivity');

Now, every visit is logged automatically!


3️⃣ Cleaning & Modifying Input Before It Reaches Controllers

Modify or sanitize user input before it gets processed. This is great for data consistency across your app.

💡 Example: Convert all email inputs to lowercase

public function handle(Request $request, Closure $next)
{
    if ($request->has('email')) {
        $request->merge(['email' => strtolower($request->email)]);
    }
    return $next($request);
}

How to use it:

Route::post('/register', 'AuthController@register')->middleware('normalizeEmail');

Now, all email inputs are automatically converted to lowercase.


4️⃣ Restricting Access (IP Whitelisting, Maintenance Mode)

Need to temporarily block users while performing updates but continue access to specific IPs (like your dev team).

💡 Example: Allow only users from a specific office IP

public function handle(Request $request, Closure $next)
{
    $allowedIps = ['123.456.789.1']; // Replace with your office IP

    if (!in_array($request->ip(), $allowedIps)) {
        return response('Site is under maintenance', 503);
    }
    return $next($request);
}

How to use it:

Route::get('/admin', function () {
    return view('admin.dashboard');
})->middleware('restrictByIp');

Now, only approved IPs can access the admin panel.


5️⃣ Automatic Language Switching

Want to switch the app language based on user request? Middleware can detect the lang query parameter and set the language automatically.

💡 Example: If a user visits /?lang=fr, the app switches to French

public function handle(Request $request, Closure $next)
{
    if ($request->has('lang')) {
        app()->setLocale($request->lang);
    }
    return $next($request);
}

How to use it:

Route::get('/', function () {
    return view('welcome');
})->middleware('setLanguage');

Now, the app automatically sets the language based on the URL parameter.


6️⃣ Perform an Action After the Request

Middleware isn’t just for before requests—it can also run after the response is sent. This is useful for tasks like logging, cleanup, or modifying the response before it's sent back to the user.

💡 Example: Log response time for performance monitoring

Want to measure how long a request takes to process? Middleware can track the time and log it for performance insights.

public function handle(Request $request, Closure $next)
{
    $start = microtime(true); // Record start time

    $response = $next($request);

    $duration = microtime(true) - $start; // Calculate execution time
    \Log::info("Request to {$request->path()} took {$duration} seconds");

    return $response;
}

Now, every request logs its execution time, helping you spot slow endpoints.

Final Thoughts

If you're copy-pasting the same logic in multiple controllers, stop right there. Middleware is made for this. Your controllers should focus on actual business logic, not random repetitive tasks—middleware keeps it that way.

So next time you think, “I need to do this before or after every request,"that’s your signal to create a middleware! 🚀

Want to receive more articles like this?

Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.

Reactions & Comments

What do you think about this?

Latest Articles

Wondering what our community has been up to?