Inicio > Desarrollo Web > Tutoriales de Laravel > Cómo Añadir Excepciones de IP en Rutas y Modo Mantenimiento en Laravel 5.2

Cómo Añadir Excepciones de IP en Rutas y Modo Mantenimiento en Laravel 5.2

Diego Cortés
Diego Cortés
November 26, 2016
Cómo Añadir Excepciones de IP en Rutas y Modo Mantenimiento en Laravel 5.2

¡Hola! En esta oportunidad, les mostraré cómo agregar excepciones de IP en modo mantenimiento en Laravel 5.2. Este proceso es bastante necesario antes de pasar a producción cualquier nueva aplicación o para realizar modificaciones en el sistema.

Siempre he utilizado excepciones por IP, pero recientemente me encontré con un caso en el que un externo (Mailgun para la verificación de empresa) necesitaba acceder a una sección de la aplicación, como los términos y condiciones, políticas de privacidad y el checkbox en el registro de usuarios.

Dado que no tenía forma de conocer la IP de este externo y la aplicación aún no estaba lista para producción, no podía desactivar el modo mantenimiento. Por lo tanto, tuve que encontrar una solución para permitir el acceso a ciertas rutas independientemente de la IP. ¡Así que vamos a ello!

El modo de mantenimiento de Laravel ya trae un middleware por defecto si revisamos el archivo Kernel.php ubicado en "app/Http"

veremos lo sgte:

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

Este middleware por defecto no nos brinda excepciones así que lo que haremos será crear un nuevo middleware que reemplazará al por defecto.

Crearemos un nuevo archivo llamado CheckForMaintenanceMode dentro de "app/Http/Middleware/" y dentro de este archivo pegaremos lo siguiente:

<?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);
    }
}

Como ven es muy parecido al originar el cual pueden encontrar en:

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

Ahora agregaremos primero que nada la excepción por ip única o múltiples

agregaremos a nuestra clase CheckForMaintenanceMode la variable

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

y el condicional

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

le agregaremos la condición

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

quedando el condicional completo así:

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

Ahora agregaremos la otra excepción por rutas, para ello agregamos otra variable a nuestra clase CheckForMaintenanceMode

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

y dentro del condicional agregaremos lo siguiente:

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

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

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

Si se fijan, recorro el array $except (variable), si no es / , quito con trim los / y posteriormente consultamos si es la ruta en que estamos actualmente, si es la ruta, continuamos, de lo contrario lanzamos un 503 por que no es una excepción, finalmente en nuestro archivo Kernel.php ubicado en:

"app/Http"

reemplazamos el middleware a utilizar

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

por el nuevo:

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

eso es todo, les dejo el código completo de nuestro nuevo middleware CheckForMaintenanceMode, espero a más de alguien le sirva !

PD: Disculpen si fui muy lento y específico, la idea es que sirva tambien para aquellos que recién comiencen en 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

Categorías

Page loaded in 33.21 ms