Laravel Middleware - Block IPs using Middleware class
When talking about securing the Laravel application, we might also want to restrict IP address to access our application, especially when we have Laravel setup as a Backend server providing data through APIs or web services.
As of today, you might find no. of Laravel package providing IP address restriction functionality but I found it does not make any sense to install a package when it is achieved through only One class.
Yes! we can just do this with a simple middleware class.
Let me explain to you little details on how we can achieve it using the Middleware class.
First, let's create a middleware class using the Laravel artisan command:
php artisan make:middleware RestrictIPAddress
It will create a new class in your Laravel project under the `app/Http/Middleware` directory.
It will have a default empty method handle(), where you have to write your logic.
Logic is simple, you just have to get the IP address from where the request is coming. here is the method to get IP from the incoming requests.
private function getRequestingIp(): string { $server = request()->server->all(); if (isset($server['HTTP_X_FORWARDED_FOR'])) { $ip_addresses = explode(',', $server['HTTP_X_FORWARDED_FOR']); return trim(end($ip_addresses)); } return $server['REMOTE_ADDR']; }
Once we got the request source IP, we compare this IP to our list of given IPs and will allow OR restrict the request ahead to application.
Here is one point to note, Restrict IPs can work in both ways, either you Block some IPs or you Allow only some IPs i.e. as per the requirements. So you can use the same middleware class to restrict IPs either by blocking the given list of IPs or Allowing only the given list of IPs.
Here I want to block the given list of IPs, I will check if the requesting IP matches in the given list of IPs, and the request will be blocked and will show the suitable message as a response.
If the requesting IP is not in the given Block IPs list, it will simply be forwarded to the application.
Here is the content of the handle method which is the main method of our middleware class:
public function handle(Request $request, Closure $next) { $this->restrictedIp = explode(',', env('BLOCK_IPs')); if (in_array($this->getRequestingIp(), $this->restrictedIp)) { return response()->json(['message' => "You are not allowed to access this site."], 403); } return $next($request); }
Here I am getting list IPs to block from ENV variables, you can also put them in any config file or in the Middleware class property itself. I preferred ENV to avoid unnecessary deployment just to update the block IPs list.
So our complete Middleware class will look like this:
namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class RestrictIpAddressMiddleware { private $restrictedIp = []; /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle(Request $request, Closure $next) { $this->restrictedIp = explode(',', env('BLOCK_IPs')); if (in_array($this->getRequestingIp(), $this->restrictedIp)) { return response()->json(['message' => "You are not allowed to access this site."], 403); } return $next($request); } private function getRequestingIp(): string { $server = request()->server->all(); if (isset($server['HTTP_X_FORWARDED_FOR'])) { $ip_addresses = explode(',', $server['HTTP_X_FORWARDED_FOR']); return trim(end($ip_addresses)); } return $server['REMOTE_ADDR']; } }
In getRequestingIp() method, i consider $server['HTTP_X_FORWARDED_FOR'] incase the incoming request to forwarded request from inmiddle server or proxy server. otherwise we can get requesting IP simply from $server['REMOTE_ADDR'].
Now you can test this by adding your local machine IP in comma separate Block IPs list stored in ENV variable.
Comments
Post a Comment