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.

Like our articles?
Check out our Laravel online courses!

2 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here