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:
php artisan make:middleware IPAddresses
Then we go into generated app/Http/Middleware/IPAddresses.php and add this:
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:
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:
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.
No comments or questions yet...