Navigation

Laravel

How to Get the Client's IP Address from a Request

Retrieve real client IP addresses in Laravel, handling proxies, load balancers, and CDNs. Essential for rate limiting, logging, and geolocation.

Table Of Contents

Problem

You need to get the real client IP address for logging, rate limiting, or geolocation, but your app is behind proxies or load balancers showing incorrect IPs.

Solution

Use Laravel's built-in methods and handle proxy configurations:

// Basic IP retrieval
$clientIp = request()->ip();

// Or in controller
public function someMethod(Request $request)
{
    $ip = $request->ip();
    
    // Log or use the IP
    Log::info("Request from IP: {$ip}");
    
    return response()->json(['your_ip' => $ip]);
}

Handle proxies and load balancers properly:

// Configure trusted proxies in app/Http/Middleware/TrustProxies.php
<?php

namespace App\Http\Middleware;

use Illuminate\Http\Middleware\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    protected $proxies = [
        '192.168.1.0/24',    // Internal network
        '10.0.0.0/8',        // Private network
        '*',                 // Trust all proxies (use with caution)
    ];

    protected $headers = [
        \Illuminate\Http\Request::HEADER_X_FORWARDED_FOR,
        \Illuminate\Http\Request::HEADER_X_FORWARDED_HOST,
        \Illuminate\Http\Request::HEADER_X_FORWARDED_PORT,
        \Illuminate\Http\Request::HEADER_X_FORWARDED_PROTO,
    ];
}

Advanced IP detection with fallbacks:

class IpService
{
    public static function getRealIp(Request $request): string
    {
        // Check for trusted proxy headers first
        if ($request->ip()) {
            return $request->ip();
        }
        
        // Fallback checks for various headers
        $headers = [
            'HTTP_CF_CONNECTING_IP',     // Cloudflare
            'HTTP_X_REAL_IP',            // Nginx
            'HTTP_X_FORWARDED_FOR',      // Standard proxy header
            'HTTP_CLIENT_IP',            // Proxy
            'REMOTE_ADDR'                // Direct connection
        ];
        
        foreach ($headers as $header) {
            if (!empty($_SERVER[$header])) {
                $ip = $_SERVER[$header];
                
                // Handle comma-separated IPs
                if (strpos($ip, ',') !== false) {
                    $ip = trim(explode(',', $ip)[0]);
                }
                
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
        
        return $request->ip() ?? '0.0.0.0';
    }
}

Why It Works

Laravel's request()->ip() automatically handles proxy headers when TrustProxies middleware is configured correctly. It checks X-Forwarded-For and other proxy headers to find the real client IP, falling back to the direct connection IP when no proxy is detected.

Practical usage examples:

// Rate limiting by IP
$key = 'api_limit:' . request()->ip();
if (Cache::get($key, 0) >= 100) {
    abort(429, 'Rate limit exceeded');
}
Cache::increment($key, 1);
Cache::expire($key, 3600);

// Geolocation
$ip = request()->ip();
$location = Http::get("http://ip-api.com/json/{$ip}")->json();

// Security logging
Log::info('Login attempt', [
    'ip' => request()->ip(),
    'user_agent' => request()->userAgent(),
    'user_id' => auth()->id()
]);

// Country-based redirects
$userCountry = geoip(request()->ip())->country;
if ($userCountry === 'US') {
    return redirect('https://us.example.com');
}

Related: Laravel Collections: Beyond Basic Array Operations | Laravel Events and Listeners: Building Decoupled Applications | Building Multi-tenant Applications with Laravel: A Comprehensive Guide | Laravel API Rate Limiting: Protect Your Endpoints from Abuse | Security Best Practices: Web Application Security

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Laravel