EN ES
Home > Web development > Laravel Tutorials > How to Add IP Exceptions in Routes and Maintenance Mode in Laravel 5.2

How to Add IP Exceptions in Routes and Maintenance Mode in Laravel 5.2

Diego Cortés
Diego Cortés
November 26, 2016
How to Add IP Exceptions in Routes and Maintenance Mode in Laravel 5.2

Hello! This time, I'll show you how to add IP exceptions in maintenance mode in Laravel 5.2. This process is quite necessary before moving any new application to production or to make modifications to the system.

I've always used IP exceptions, but recently I came across a case where an external party (Mailgun for company verification) needed to access a section of the application, such as the terms and conditions, privacy policies, and the checkbox in user registration.

Since I had no way of knowing the IP of this external party and the application was not yet ready for production, I couldn't disable maintenance mode. Therefore, I had to find a solution to allow access to certain routes regardless of the IP. So, let's get to it!

Laravel's maintenance mode already comes with a middleware by default if we check the Kernel.php file located in "app/Http"

We'll see the following:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];

This default middleware does not provide us with exceptions so what we will do is create a new middleware that will replace the default one.

We will create a new file called CheckForMaintenanceMode inside "app/Http/Middleware/" and inside this file we will paste the following:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Response;

class CheckForMaintenanceMode
{

    /**
    * The application implementation.
    *
    * @var \Illuminate\Contracts\Foundation\Application
    */
    protected $app;

    /**
    * Create a new middleware instance.
    *
    * @param \Illuminate\Contracts\Foundation\Application $app
    * @return void
    */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }

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

        if ($this->app->isDownForMaintenance()))
        {
            //Reviso si esta en la exceltion
            foreach ($this->except as $except) {
                if ($except !== '/') {
                    $except = trim($except, '/');
                }

            }
            return response()->view(‘errors.503’);
        }

        return $next($request);
    }
}

As you can see, it is very similar to the original one which you can find at:

vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php

Now we will first add the exception for single or multiple IPs

We will add the variable to our CheckForMaintenanceMode class

protected $ips =
[
    '255.255.255.255',
    '244.244.244.244'
];

and the conditional

if ($this->app->isDownForMaintenance()))

We will add the condition

!in_array($request->getClientIp(), $this->ips)

the complete conditional being like this:

if ($this->app->isDownForMaintenance() && !in_array($request->getClientIp(), $this->ips))

Now we will add the other exception by routes, for this we add another variable to our CheckForMaintenanceMode class

protected $except =
[
    'info/politicas-de-privacidad',
    'info/terminos-y-condiciones'
];

and inside the conditional we will add the following:

//Check if I have the exception
foreach ($this->except as $except) {
    if ($except !== '/') {
        $except = trim($except, '/');
    }

    if ($request->is($except)) {
        return $next($request);
    }

}
return response()->view('errors.503');

If you notice, I go through the $except array (variable), if it is not / , I remove the / with trim and then we check if it is the route we are currently on, if it is the route, we continue, otherwise we throw a 503 because it is not an exception, finally in our Kernel.php file located at:

"app/Http"

We replace the middleware to be used

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];

for the new one:

protected $middleware = [
     \App\Http\Middleware\CheckForMaintenanceMode::class,
];

That's all, here is the complete code for our new CheckForMaintenanceMode middleware, I hope it helps more people!

PS: Sorry if I was too slow and specific, the idea is that it also helps those who are just starting out with Laravel
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Response;

class CheckForMaintenanceMode
{

    /**
    * The application implementation.
    *
    * @var \Illuminate\Contracts\Foundation\Application
    */
    protected $app;

    /**
    * Create a new middleware instance.
    *
    * @param \Illuminate\Contracts\Foundation\Application $app
    * @return void
    */
    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    /**
    *
    * Routes for exception
    *
    */
    protected $except =
    [
        'info/politicas-de-privacidad',
        'info/terminos-y-condiciones'
    ];

    /**
    *
    * IPS for exception
    *
    */
    protected $ips =
    [
        '255.255.255.255',
        '244.244.244.244'
    ];

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

        if ($this->app->isDownForMaintenance() && !in_array($request->getClientIp(), $this->ips))
        {
            //Bucle for routes
            foreach ($this->except as $except) {
                if ($except !== '/') {
                    //Clean url
                    $except = trim($except, '/');
                }
                //If is exception route
                if ($request->is($except)) {
                    return $next($request);
                }
            }
            //Is not exception IP and not exception route launch 503
            return response()->view('errors.503');
        }

       return $next($request);
    }
}


Diego Cortés
Diego Cortés
Full Stack Developer, SEO Specialist with Expertise in Laravel & Vue.js and 3D Generalist

Categories

Page loaded in 33.96 ms