fideloper/proxy
Laravel trusted proxy middleware that correctly detects HTTPS, host, and client IP behind load balancers and reverse proxies by handling X-Forwarded-* headers. Fixes URL generation and request data when running behind ELB, Cloudflare, Nginx, etc.
composer require fideloper/proxy
php artisan vendor:publish --provider="Fideloper\Proxy\TrustProxiesServiceProvider" --tag="config"
app/Http/Kernel.php:
protected $middleware = [
// ...
\Fideloper\Proxy\TrustProxies::class,
];
config/trustproxies.php:
'proxies' => '192.168.1.1, 127.0.0.1', // Comma-separated list of trusted proxy IPs
Fix HTTPS detection behind a proxy: If your app redirects HTTP → HTTPS but fails due to proxy headers, enable:
'trusted_proxies' => '*', // Trust all proxies (use cautiously)
'headers' => TrustProxies::HEADER_X_FORWARDED_ALL, // Trust X-Forwarded-* headers
Trusting Proxies:
proxies => '192.168.1.1'proxies => '192.168.1.0/24'proxies => '*' (use only in trusted environments like staging).Header Configuration:
X-Forwarded-* headers:
'headers' => TrustProxies::HEADER_X_FORWARDED_ALL
'headers' => TrustProxies::HEADER_X_FORWARDED_FOR | TrustProxies::HEADER_X_FORWARDED_HOST
Dynamic Trust:
TrustProxies::check() in middleware to conditionally trust proxies:
if (TrustProxies::check($request)) {
// Proceed with trusted logic
}
Laravel URL Generation:
The package ensures url(), secure_url(), and asset() generate correct URLs behind proxies.
Example:
$url = url('/dashboard'); // Now respects X-Forwarded-Host
Rate Limiting:
Use TrustProxies::ip() to get the real client IP for accurate rate limiting:
RateLimiter::for('api')->by($request->ip()); // Fallback to TrustProxies::ip()
Logging: Log the real client IP using:
\Log::info('Client IP', ['ip' => TrustProxies::ip($request)]);
Middleware Stacking:
Place TrustProxies before other middleware that relies on accurate request data (e.g., VerifyCsrfToken).
Over-Trusting Proxies:
proxies => '*' exposes your app to header spoofing. Restrict to known IPs in production.'proxies' => '10.0.0.0/8, 172.16.0.0/12'
Mixed Content Redirects:
secure_url() generates HTTP links behind HTTPS proxies, ensure:
'trusted_proxies' => env('TRUSTED_PROXIES', '127.0.0.1, ::1'),
'headers' => TrustProxies::HEADER_X_FORWARDED_ALL,
'scheme' => 'https', // Force HTTPS if behind a proxy
Local Development Issues:
localhost, use:
'proxies' => '127.0.0.1, ::1'
* in local environments to prevent header spoofing.Cloudflare/ELB Headers:
CF-Connecting-IP. To trust it, extend the package:
TrustProxies::setHeader('CF-Connecting-IP', 'X-Forwarded-For');
Verify Trusted IPs:
if (!TrustProxies::check($request)) {
\Log::warning('Request not from a trusted proxy', ['ip' => $request->ip()]);
}
Inspect Headers: Dump forwarded headers to debug:
\Log::debug('Forwarded Headers', [
'X-Forwarded-For' => $request->header('X-Forwarded-For'),
'X-Forwarded-Host' => $request->header('X-Forwarded-Host'),
]);
Custom Headers:
Extend the package to trust additional headers (e.g., X-Real-IP):
TrustProxies::setHeader('X-Real-IP', 'X-Forwarded-For');
Dynamic Proxy Lists: Load trusted proxies from an external source (e.g., API):
$trustedProxies = config('services.trusted_proxies_api');
TrustProxies::setTrustedProxies($trustedProxies);
Middleware Logic: Override the default middleware behavior:
public function handle($request, Closure $next) {
if (app()->environment('production')) {
TrustProxies::setTrustedProxies(['192.168.1.1']);
}
return $next($request);
}
Testing: Mock proxies in tests:
TrustProxies::setTrustedProxies(['127.0.0.1']);
$request = new Request([], [], [], [], [], ['HTTP_X_FORWARDED_FOR' => '192.168.1.100']);
How can I help you explore Laravel packages today?