set $ _SERVER ['HTTP_CLIENT_IP']的值是否为空字符串?

时间:2011-10-01 21:50:01

标签: php ip web

我有一个简单的脚本来确定用户的IP地址:

function GetIp(){
      if (!empty($_SERVER['HTTP_CLIENT_IP']))
      //check ip from share internet
      {
        $ip=$_SERVER['HTTP_CLIENT_IP'];
      }
      elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
      //to check ip is pass from proxy
      {
        $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
      }
      else
      {
        $ip=$_SERVER['REMOTE_ADDR'];
      }
      return $ip;
}

现在在网上我看到有人使用这个脚本:

if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
        $Ip = $_SERVER['HTTP_CLIENT_IP'];
    elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
        $Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
        $Ip = $_SERVER['REMOTE_ADDR'];

我想知道我的实现是否已损坏..我是否需要检查$_SERVER['HTTP_CLIENT_IP']$_SERVER['HTTP_X_FORWARDED_FOR']$_SERVER['REMOTE_ADDR']的值是否为空?或者实际上没必要这样做?

4 个答案:

答案 0 :(得分:14)

如果你想找出客户端的IP地址的原因非常重要,那就搞砸了所有这些。

这些标头值中的任何一个都可以自由欺骗。

REMOTE_ADDR是唯一真正可靠的信息,因为它是由处理请求的Web服务器传输给您的。它理论上可以是falsified as well,但这比欺骗标题值要困难得多,而且是一种完全不同的攻击类别。

在反向代理背后的非常非常具体的托管环境中有例外。在这些情况下,管理该代理的人将能够告诉您需要测试哪个标头值。

答案 1 :(得分:8)

来自Kohanas的请求类:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    AND isset($_SERVER['REMOTE_ADDR'])
    AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
    // Use the forwarded IP address, typically set when the
    // client is using a proxy server.
    // Format: "X-Forwarded-For: client1, proxy1, proxy2"
    $client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);

    Request::$client_ip = array_shift($client_ips);

    unset($client_ips);
}
elseif (isset($_SERVER['HTTP_CLIENT_IP'])
    AND isset($_SERVER['REMOTE_ADDR'])
    AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
    // Use the forwarded IP address, typically set when the
    // client is using a proxy server.
    $client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);

    Request::$client_ip = array_shift($client_ips);

    unset($client_ips);
}
elseif (isset($_SERVER['REMOTE_ADDR']))
{
    // The remote IP address
    Request::$client_ip = $_SERVER['REMOTE_ADDR'];
}

这非常好。在这种情况下,请注意Request::$trusted_proxies数组以及$ip var为Request::$client_ip

答案 2 :(得分:7)

除非您明确知道您的应用程序是在反向代理后面配置的,否则请勿检查客户端IP的任何HTTP_*标头。无条件地信任这些标头的值将允许用户欺骗他们的IP地址。

包含可靠值的唯一$_SERVER字段为REMOTE_ADDR

答案 3 :(得分:1)

这两件事实际上是相同的。在你发现的脚本中,作者只是检查数组中的元素是否在检查它是非空的之前是否已设置。

关于使用empty() - 函数而不是比较,请检查http://php.net/empty。由于您正在处理由环境而不是用户输入设置的变量,因此您选择的两个选项中的哪一个无关紧要。所以你的脚本应该是完美的