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

发布于 2024-12-07 14:06:55 字数 1087 浏览 0 评论 0原文

我有一个简单的脚本来确定用户的 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'] 为空?或者实际上没有必要这样做?

I have a simple script which determines the user's IP address:

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;
}

Now on the Net somewhere I saw someone using this script:

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'];

I was wondering if my implementation is broken.. Do I need to check if the value of $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'], or $_SERVER['REMOTE_ADDR'] is empty? Or is it actually unnecessary to do so?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

五里雾 2024-12-14 14:06:55

如果你想找出客户端 IP 地址的原因真的很重要,那就把这些都搞砸吧。

这些标头值中的任何一个都可以被随意欺骗。

REMOTE_ADDR 是唯一真正可靠的信息,因为它是由处理请求的 Web 服务器传输给您的。理论上它也可以被伪造,但这比欺骗标头值和完全不同的类要困难得多的攻击。

在反向代理背后的非常非常特定的托管环境中也有例外。在这些情况下,管理该代理的人员将能够知道您需要测试什么标头值。

If the reason why you want to find out the client's IP address is really important, screw all this stuff.

Any one of these header values can be freely spoofed.

REMOTE_ADDR is the only really reliable information, as it is transmitted to you by your web server that is handling the request. It can be theoretically falsified as well, but that is much, much harder than spoofing a header value, and an entirely different class of attack.

There are exceptions in very, very specific hosting environments behind reverse proxies. In those cases the person administering that proxy will be able to tell what header value you need to test for.

失与倦" 2024-12-14 14:06:55

来自 Kohanas 的 Request 类:

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

From Kohanas' Request class:

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'];
}

This is pretty much as good as it gets. Please note the Request::$trusted_proxies array and that your $ip var is Request::$client_ip in this case.

遗忘曾经 2024-12-14 14:06:55

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

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

Do not check any HTTP_* headers for the client IP unless you specifically know your application is configured behind a reverse proxy. Trusting the values of these headers unconditionally will allow users to spoof their IP address.

The only $_SERVER field containing a reliable value is REMOTE_ADDR.

少钕鈤記 2024-12-14 14:06:55

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

关于使用 empty() 函数而不是比较,请检查 http://php.ini。净/空。由于您处理的是由环境设置的变量,而不是用户输入的变量,因此您选择两个选项中的哪一个并不重要。所以你的脚本应该完全没问题

The two things are practically identical.. In the script you found, the author is just doing a check if the element in the array is set before checking that it is non-empty.

In regards to using the empty()-function instead of the comparison, check http://php.net/empty. Since you are dealing with a variable that is set by the environment and not a user input it doesn't matter which of the two options you choose. So your script should be perfectly fine

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文