middlewares/client-ip
A Laravel middleware for reliably resolving the client's real IP address, including requests passing through proxies, load balancers, and CDNs. Supports forwarded headers and configurable trusted proxies for accurate IP detection.
Architecture fit. The package is a single-responsibility PSR-15 middleware that resolves the client IP and writes it to a request attribute. That is a clean, low-coupling design: it composes into any PSR-7/PSR-15 pipeline (Slim, Laminas/Mezzio, Expressive successors, Symfony via bridge) without touching application code. One important caveat for the stated context: this is not a Laravel-native middleware. Laravel's HTTP kernel uses its own handle($request, Closure $next) contract, not PSR-15, so adoption in a Laravel codebase requires an adapter/bridge or a wrapper middleware that delegates to the PSR-15 instance. That is a real, if small, integration cost—and it raises the question of whether the package is being pulled in for a Laravel app at all, or whether the framing in the request is inaccurate.
Integration feasibility. The functional surface is tiny (detect IP → set attribute), so the integration is nearly trivial in a PSR-15 host and modest in Laravel. There are no database, queue, or config-heavy dependencies implied. The main feasibility gates are (a) which PSR-7 implementation you run, (b) whether the attribute key is configurable or hard-coded, and (c) whether the package respects a trusted-proxy configuration. Those are answerable in an afternoon of spike work.
Technical risk. Several signals warrant caution:
X-Forwarded-For chains, trusted-proxy allowlists, Cloudflare/ALB headers, IPv4-mapped IPv6, and header spoofing. A naive implementation can silently return an attacker-controlled value.Key questions.
Request::ip() with TrustProxies, or Symfony's Request::getClientIp())?Stack fit. In a PSR-15-native stack (Slim, Mezzio), this drops in as one line in the middleware pipeline and is a good fit. In Laravel or Symfony, it duplicates functionality the framework already provides and ships with mature trusted-proxy handling—so the value proposition weakens considerably. If the target is Laravel, the honest recommendation is to prefer the framework primitive unless there is a specific reason (e.g., a shared middleware library across multiple frameworks).
Migration path. Adoption and removal are both cheap: register the middleware, consume the attribute, delete if needed. There is no schema, no persistent state, and no data migration. The only lock-in is the attribute key name leaking into downstream code—mitigate by reading it through a thin internal accessor rather than stringly-typed lookups scattered across the codebase.
Compatibility. Confirm PSR-15 v1 vs. v2, PSR-7 implementation compatibility (Nyholm, Laminas Diactoros, Guzzle), and the supported PHP range against our runtime. For Laravel, verify the bridge package is itself maintained. Test in a staging environment behind the actual edge (CDN/LB) before trusting the resolved value.
Sequencing.
Maintenance. This is the dominant concern. A 16-star package with an unknown repository and a single recent release should be treated as effectively unmaintained until proven otherwise. Pin the exact version, vendor or mirror the source, and add it to a dependency-review watchlist. Budget for the possibility of forking and owning ~100 lines of code—which is arguably the better outcome given the scope.
Support. No commercial support, no visible maintainer SLAs, limited community. Internal expertise must cover it.
Scaling. Runtime cost is negligible—a header parse and one attribute write per request. No memory, connection, or I/O implications. It will not be a bottleneck at any realistic throughput.
Failure modes.
Ramp-up. Very low for engineers familiar with PSR-15: the concept and code are small. Laravel-only engineers will need a short explanation of the PSR-15 bridge and, more importantly, an explanation of why this exists alongside $request->ip(). Document the attribute contract and the trusted-proxy assumptions in the team's runbook; those two facts are what future responders will need at 3 a.m.
How can I help you explore Laravel packages today?