如何从访客获得真实IP?

85 php ip

我正在使用这个PHP代码来获取访问者的IP地址:

<?php echo $_SERVER['REMOTE_ADDR']; ?>
Run Code Online (Sandbox Code Playgroud)

但是,当他们使用代理时,我无法从访问者那里获得真正的IP地址.在这种情况下,有没有办法获取访问者的IP地址?

小智 158

试试这个PHP代码.

<?PHP

function getUserIP()
{
    // Get real visitor IP behind CloudFlare network
    if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
              $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
              $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
    }
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP))
    {
        $ip = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP))
    {
        $ip = $forward;
    }
    else
    {
        $ip = $remote;
    }

    return $ip;
}


$user_ip = getUserIP();

echo $user_ip; // Output IP address [Ex: 177.87.193.134]


?>
Run Code Online (Sandbox Code Playgroud)

  • 这很糟糕,因为`HTTP_CLIENT_IP`和`HTTP_X_FORWARDED_FOR`可以伪造.只有`REMOTE_ADDR`不能. (24认同)
  • 您还应该处理涉及多个代理的情况,为什么不呢? (4认同)
  • @Pradeep Kumar Prabaharan,是的。如果在本地服务器上运行此代码,则将获得本地IP,即127.0.0.1或:: 1 (2认同)
  • HTTP_X_FORWARDED_FOR可以有多个IP,例如“ 1.1.1.1,2.2.2.2”,此功能无法处理。阅读https://en.wikipedia.org/wiki/X-Forwarded-For (2认同)

Ten*_*eff 40

这是我见过的最常见的技术:

function getUserIP() {
    if( array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) {
        if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')>0) {
            $addr = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']);
            return trim($addr[0]);
        } else {
            return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    else {
        return $_SERVER['REMOTE_ADDR'];
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,它并不能保证您始终可以获得正确的用户IP,因为有很多方法可以隐藏它.

  • @Garconis 这里没有人没有提到过 WordPress (2认同)

El *_*ero 18

这是我的方法:

 function getRealUserIp(){
    switch(true){
      case (!empty($_SERVER['HTTP_X_REAL_IP'])) : return $_SERVER['HTTP_X_REAL_IP'];
      case (!empty($_SERVER['HTTP_CLIENT_IP'])) : return $_SERVER['HTTP_CLIENT_IP'];
      case (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) : return $_SERVER['HTTP_X_FORWARDED_FOR'];
      default : return $_SERVER['REMOTE_ADDR'];
    }
 }
Run Code Online (Sandbox Code Playgroud)

如何使用:

$ip = getRealUserIp();
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常奇怪和令人困惑的switch语句使用.http://www.codethinked.com/dont-be-clever (15认同)
  • 你认为究竟会混淆什么?对我来说,很明显! (9认同)
  • 这很令人困惑,因为这正是if/elseif的用途. (4认同)
  • 如果您发现自己使用switch(true),请停止并使用if语句.怎么可能比被接受的if/else更清楚? (4认同)

Hal*_*yon 7

代理可以发送HTTP_X_FORWARDED_FOR标题,但即使这是可选的.

另请注意,访问者可以共享IP地址; 大学网络,大型公司和第三世界/低预算的ISP倾向于与许多用户共享IP.


小智 5

应用此代码获取ipaddress:

    if (getenv('HTTP_X_FORWARDED_FOR')) { $pipaddress = getenv('HTTP_X_FORWARDED_FOR');
 $ipaddress = getenv('REMOTE_ADDR'); 
    echo "Your Proxy IP address is : ".$pipaddress. "(via $ipaddress)" ; } 
    else { $ipaddress = getenv('REMOTE_ADDR'); echo "Your IP address is : $ipaddress"; }
    ------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)


Ehs*_*shi 5

这是我的职责。

好处 :

  • 如果 $_SERVER 不可用,则工作。
  • 过滤私有和/或保留IP;
  • 处理X_FORWARDED_FOR中所有转发的IP
  • 与 CloudFlare 兼容
  • 如果找不到有效 IP,可以设置默认值!
  • 简短又简单!

/**
 * Get real user ip
 *
 * Usage sample:
 * GetRealUserIp();
 * GetRealUserIp('ERROR',FILTER_FLAG_NO_RES_RANGE);
 * 
 * @param string $default default return value if no valid ip found
 * @param int    $filter_options filter options. default is FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
 *
 * @return string real user ip
 */

function GetRealUserIp($default = NULL, $filter_options = 12582912) {
    $HTTP_X_FORWARDED_FOR = isset($_SERVER)? $_SERVER["HTTP_X_FORWARDED_FOR"]:getenv('HTTP_X_FORWARDED_FOR');
    $HTTP_CLIENT_IP = isset($_SERVER)?$_SERVER["HTTP_CLIENT_IP"]:getenv('HTTP_CLIENT_IP');
    $HTTP_CF_CONNECTING_IP = isset($_SERVER)?$_SERVER["HTTP_CF_CONNECTING_IP"]:getenv('HTTP_CF_CONNECTING_IP');
    $REMOTE_ADDR = isset($_SERVER)?$_SERVER["REMOTE_ADDR"]:getenv('REMOTE_ADDR');

    $all_ips = explode(",", "$HTTP_X_FORWARDED_FOR,$HTTP_CLIENT_IP,$HTTP_CF_CONNECTING_IP,$REMOTE_ADDR");
    foreach ($all_ips as $ip) {
        if ($ip = filter_var($ip, FILTER_VALIDATE_IP, $filter_options))
            break;
    }
    return $ip?$ip:$default;
}
Run Code Online (Sandbox Code Playgroud)