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:
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...

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 58 courses (1056 lessons, total 44 h 09 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials