How to check access to Laravel project by IP address
From time to time I see a need of restricting the access to a website by IP address, whether it’s local network or a particular set of specific computers, like home/office. What’s the best way to do that in Laravel?
There’s no “official” prepared solution for this in Laravel core, but we can use a concept of Middleware to create our own class for restrictions.
So we run:
1 2 3 |
php artisan make:middleware IPAddresses |
Then we go into generated app/Http/Middleware/IPAddresses.php and add this:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class IPAddresses { public function handle($request, Closure $next) { if ($request->ip() != 'xxx.xxx.xxx.xxx') { abort(403); } return $next($request); } } |
There are a few things to notice here:
- There are multiple ways to get client’s IP address – you can also use $_SERVER[‘REMOTE_ADDR’] from PHP directly or something more complicated like this;
- Instead of abort(403); you can do something like redirect() to some page with message or errors.
To user your Middleware class, you need to register it in app/Kernel.php:
1 2 3 4 5 6 7 8 |
protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, // ... other middleware classes \App\Http\Middleware\IPAddresses::class, ]; |
This approach is not really flexible, so if you want something more robust, check this snippet by Bobby Bouwmann on Laracasts forum:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
namespace App\Http\Middleware; use Closure; use Symfony\Component\HttpFoundation\IpUtils; class RedirectInvalidIPs { /** * List of valid IPs. * * @var array */ protected $ips = [ '42.60.187.198', '188.102.29.159', ]; /** * List of valid IP-ranges. * * @var array */ protected $ipRanges = [ '12.64.103.24', ]; /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { foreach ($request->getClientIps() as $ip) { if (! $this->isValidIp($ip) && ! $this->isValidIpRange($ip)) { return redirect('/'); } } return $next($request); } /** * Check if the given IP is valid. * * @param $ip * @return bool */ protected function isValidIp($ip) { return in_array($ip, $this->ips); } /** * Check if the ip is in the given IP-range. * * @param $ip * @return bool */ protected function isValidIpRange($ip) { return IpUtils::checkIp($ip, $this->ipRanges); } } |
Finally, you can use a package by Antonio Ribeiro called Firewall – it allows you to perform much more restrictions than just IP addresses.
You don't need any packages to do that!
I find this approach more interesting … https://github.com/skydiver/laravel-route-blocker
Great one, Martin, thanks!