Understanding Laravel Middleware

Middleware in Laravel is a bridge between all the requests and responses. Or we can say that all the requests entering your application can be filtered by middlewares. Laravel has fewer built-in middleware such as VerifyCsrfToken. The VerifyCsrfToken middleware will check the CSRF Token on each and every POST requests and through an error if the CSRF Token missed or mismatched.

Let’s understand with an example by creating custom middleware. We are going to create a basic firewall middleware. Our custom middleware will check all the IP address contained by the request and blocked the un-authenticated requests.

Table of content

Custom Middleware

Laravel provides a very convenient to increase productivity. Yes, I am talking about artisan command. It is very simple to create your custom middleware.

php artisan make:middleware Firewall

Next step is to open the Firewall Middleware from the app/Http/Middleware directory. Your middleware class should contain a similar code as below.

namespace App\Http\Middleware;

use Closure;

class Firewall
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

Next step is to add a property that can hold the array of blocked IP addresses. Let’s name it $bannedIp and blocked own IP address to test if everything works fine.

....

protected $bannedIp = [
    '127.0.0.1'
];

....

Now move to the handle() method to add the IP ban logic.

...

public function handle($request, Closure $next)
{
    if(collect($this->bannedIp)->contains($request->ip())) {
        abort(401);
    }
    
    return $next($request);
}

...

Now our middleware is complete but it’s not working with each request. Because we have to register our middleware to the kernal.php file. It is up to you from where you want to register your middleware. You can register globally or assign with a route or assign to a middleware group.

As per our Firewall Middleware, we need to register it globally. So each and every request will be filtered. Now open the kernal.php file, that you can found at app/Http directory. Find the $middleware property and add your middleware.

...

protected $middleware = [
    \App\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\TrustProxies::class,
    \App\Http\Middleware\Firewall::class, 
];

...

Now try to test your application and it should give you the output similar to below.

Laravel middleware
401 error on IP Banned

Add Additional Data to Request Array

There are some cases when we need to supply the additional data through a request array to our controller or view. In that case, we can make a custom middleware and assign middleware to the route.

Let’s understand it with our existing firewall middleware. We will add additional field and value to the request array and will access it through the controller.

public function handle($request, Closure $next)
{
    if(collect($this->bannedIp)->contains($request->ip())) {
        abort(401);
    }
    
    // Add custom data to available on every view
    $request->request->add(['custom_field' => 'custom_value']);

    return $next($request);
}

As you can see, we have used the $request->request->add() method to add additional data to the request array. Now you can access this custom_field with request() helper function or with Request class.

Route::get('/', function () {

    dd(request('custom_field'));
    return view('welcome');
});