How to get real client IP address when you use Cloudflare


In almost all case, we can get real client IP address with $_SERVER[“HTTP_CF_CONNECTING_IP”] and $_SERVER[“REMOTE_ADDR”]

function getIP(){
    return !empty($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER["REMOTE_ADDR"];
}

But in some special cases we will get proxy IP like: 66.249.82.158, check $_SERVER we will see:

$_SERVER['HTTP_FORWARDED'] = "for=xx.xx.xx.xx";
$_SERVER['HTTP_X_FORWARDED_FOR'] = "xx.xx.xx.xx,66.249.82.158";

So we have 2 methods:
Method 1:

function getRealIP(){
    if(!empty($_SERVER['HTTP_FORWARDED'])){
        return str_replace("for=","",$_SERVER['HTTP_FORWARDED']);
    }
    return !empty($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER["REMOTE_ADDR"];
}

Method 2:

function getRealIP(){
    if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
        $temp = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']);
        return $temp[0];
    }
    return !empty($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER["REMOTE_ADDR"];
}

Update: 10/13/2018, with IPv6 we see some cases like:

$_SERVER['HTTP_FORWARDED'] = "for=[2a01:4f8:c010:fb2::2]";

or

$_SERVER['HTTP_FORWARDED'] = 'for="[2a01:4f8:c010:fb2::2]"';

So, we recommenced use this function:

function getRealIP(){
    if(!empty($_SERVER['HTTP_FORWARDED'])){
        return trim(str_replace("for=","",$_SERVER['HTTP_FORWARDED']),'"[]');
    }
    return !empty($_SERVER["HTTP_CF_CONNECTING_IP"]) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER["REMOTE_ADDR"];
}

Leave a Reply