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); } }
Page loaded in 43.98 ms