Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ip Gateway Laravel Package

vcian/laravel-ip-gateway

Laravel IP Gateway adds middleware and configuration for restricting access by IP address. Easily allow or deny requests, protect routes, and manage whitelists or blacklists with a simple Laravel-friendly setup.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install with Composer:
    composer require vcian/laravel-ip-gateway
    
  2. Publish the config (the tag name may be ip-gateway; if unsure, run php artisan vendor:publish and pick the vcian/laravel-ip-gateway provider):
    php artisan vendor:publish --tag=ip-gateway
    
  3. Open config/ip-gateway.php first. That file is the whole package in practice — it holds the allow/block lists and the enable switch. Read it before touching any code; almost every behaviour you care about is a string array there.
  4. Register the middleware alias. On Laravel ≤10, add it in app/Http/Kernel.php:
    protected $routeMiddleware = [
        // ...
        'ip.gateway' => \Vcian\IpGateway\Middleware\IpGatewayMiddleware::class,
    ];
    
    On Laravel 11+:
    // bootstrap/app.php
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias(['ip.gateway' => \Vcian\IpGateway\Middleware\IpGatewayMiddleware::class]);
    })
    
    Verify the exact class name from vendor/vcian/laravel-ip-gateway/src/ — the namespace casing is the usual source of "class not found" after install.
  5. First use case: protect an internal admin or staging surface:
    Route::middleware(['web', 'ip.gateway'])->group(function () {
        Route::get('/admin', [AdminController::class, 'index']);
    });
    
    Put your own IP in the allow list before enabling it anywhere global, or you will lock yourself out on the first request.

Implementation Patterns

  • Allowlist mode (default-deny) for internal tools. Populate allowed_ips with office/VPN ranges and apply the middleware to the entire admin panel or a staging route group. This is the package's strongest fit: a cheap, request-time gate that runs before your controllers and (if ordered correctly) before expensive auth/DB work.
  • Blocklist mode for abuse. Keep allowed_ips empty and list blocked_ips for repeat offenders or scrapers. Treat this as a stopgap — it is not a substitute for throttle or a WAF, because blocked IPs rotate.
  • Environment-driven lists. Drive the config from env() so staging is restricted and local is open:
    'allowed_ips' => array_filter(explode(',', env('IP_GATEWAY_ALLOWED', ''))),
    
    Remember config:cache after changing .env — see gotchas.
  • Scope by route group, not globally, unless you mean it. Global middleware (pushing it into the web or api stack) is the blunt instrument for "maintenance mode / internal-only deployment". Route-scoped aliases are the default for per-area restrictions.
  • Defense in depth. Combine with auth so an allowlisted-but-unauthenticated request still hits your login flow:
    Route::middleware(['ip.gateway', 'auth'])->group(...);
    
  • Testing. Faking the client IP is done at the server-variable level, not with a package helper:
    $this->withServerVariables(['REMOTE_ADDR' => '203.0.113.10'])
         ->get('/admin')
         ->assertForbidden();
    
    Write one test per allowed IP, one per blocked IP, and one for the empty-list case — the last one is where most misconfigurations hide.
  • Observability. Wrap the middleware in your own thin class (or listen for the 403/redirect) to log denials with the resolved IP. Without this you get a silent 403 and no signal on whether a real user was blocked or a scanner was.
  • API surfaces. The package returns a redirect or a 403 HTML response depending on config; for JSON APIs wrap it or add an Accept: application/json-aware custom middleware so clients get a proper {"message": "Forbidden"} payload.

Gotchas and Tips

  • request()->ip() behind a load balancer. This is the number-one failure. Behind Cloudflare/ALB/nginx, the resolved IP is the proxy's, so every request looks identical and either everyone or no one is allowed. Configure TrustProxies with the correct X-Forwarded-For handling before evaluating this package.
  • IPv6 vs IPv4. ::1 and 127.0.0.1 are different strings. Local testing on localhost often resolves to ::1 and silently fails an allowlist containing only 127.0.0.1. Add both.
  • Config caching. After editing lists in .env, run php artisan config:clear (dev) or config:cache (prod). A stale cached config is the second most common "it's not working" cause.
  • Middleware order. Place the gateway after TrustProxies and before auth/bindings so rejected requests are cheap and the IP is already resolved. Ordering it before TrustProxies makes it read the proxy IP.
  • Self-lockout. Never enable a global allowlist without first confirming your own IP is in it (and that a rollback path exists — a deploy revert or an env toggle). Keep an IP_GATEWAY_ENABLED switch so a bad list can be disabled without a code change.
  • CIDR / wildcard support is not guaranteed. Small packages like this often do exact string matches only. Test 192.168.1.0/24 and 192.168.1.* explicitly; if unsupported, do range checks in a wrapping middleware rather than forking.
  • Laravel 11 alias registration. The old Kernel.php instructions in many READMEs don't apply. If the alias isn't registered in bootstrap/app.php, you get "Target class [ip.gateway] does not exist".
  • Package maturity. 43 stars and a single 2024 release means low maintenance surface but also low bus factor. Pin the version in composer.json and keep the integration behind your own middleware/facade so swapping in a hand-rolled in_array($request->ip(), config('...')) check is a 10-line change if the package goes stale.
  • Extension points are limited — the practical approach is composition: write a RestrictToAllowedIps middleware that delegates to the package's logic (or replicates its list check), giving you a place to add logging, JSON responses, and CIDR handling without modifying vendor code.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels