Skip to main content

#018 - Getting Real User IPs Behind CloudFlare & Nginx in Laravel

·268 words·2 mins· loading · loading ·

The Challenge
#

When using CloudFlare or Nginx Reverse Proxy with Laravel, you’ll often get proxy IPs of Claudflare or proxy server instead of real user IPs. Let’s fix this.

Solution Overview
#

  1. Configure Nginx to pass real IP headers
  2. Set up Laravel to trust proxies
  3. Update code to get correct IP addresses

Nginx Configuration
#

I’ve used npm - Nginx Proxy Manager to configure Nginx run in Docker. Link: Nginx Proxy Manager

Add to your npm:

image

proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;

Laravel Trust Proxies
#

Update app/Http/Middleware/TrustProxies.phpto trust CloudFlare proxies

protected $proxies = [
   '173.245.48.0/20',
        '103.21.244.0/22',
        '103.22.200.0/22',
        '103.31.4.0/22',
        '141.101.64.0/18',
        '108.162.192.0/18',
        '190.93.240.0/20',
        '188.114.96.0/20',
        '197.234.240.0/22',
        '198.41.128.0/17',
        '162.158.0.0/15',
        '104.16.0.0/13',
        '104.24.0.0/14',
        '172.64.0.0/13',
        '131.0.72.0/22',
];

protected $headers = Request::HEADER_X_FORWARDED_FOR | 
                    Request::HEADER_X_FORWARDED_HOST | 
                    Request::HEADER_X_FORWARDED_PORT | 
                    Request::HEADER_X_FORWARDED_PROTO;

Getting Real IPs
#

// Best method
  $realIP = request()->ip();

Example Implementation
#

Allow company users from specific IP ranges to access company information board. Add to routes/web.php


Route::get('/company-board', function (Request $request) {
   // Get real IP 
   $currentIp = request()->ip();
   
   // Get allowed IPs
   $allowedIps = array_filter(
       array_map('trim', explode(',', env('COMPANY_IPS', ''))), 
       fn($ip) => !empty($ip)
   );

   // Check IP access
   if (!in_array($currentIp, $allowedIps)) {
       abort(403, 'This board is only accessible from company network');
   }
 return view('company.board');
})->name('company.board');

Add company IPs to .env:

COMPANY_IPS=<company_ip_1>, <company_ip_2>, <company_ip_3>

Create a simple view for the company board resources/views/company/board.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="card">
        <div class="card-header">
            <h3 class="card-title">Welcome to Company Board</h3>
        </div>
        
        <div class="card-body">
            <div class="text-center p-4">
                <h4>Hello Company!</h4>
                <p class="text-muted">You're viewing this from a company IP address</p>
            </div>
        </div>
    </div>
</div>
@endsection

Conclusion
#

With proper configuration of Laravel, CloudFlare, and Nginx, you can securely manage real user IP addresses in your application.