首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何正确使用HTTP_X_FORWARDED_FOR?

如何正确使用HTTP_X_FORWARDED_FOR?
EN

Stack Overflow用户
提问于 2012-07-12 21:31:35
回答 7查看 127K关注 0票数 42

好吧,我有一个小的身份验证问题。我的web服务允许使用用户名和密码通过HTTP连接到我的API,但此连接也可以限制为特定的IP地址。

这意味着$_SERVER['REMOTE_ADDR']可能是不正确的。我已经知道,任何IP信息都不能真正依赖-我的限制只是为了增加另一层安全。

如果这是对我的web服务器的请求的一般概述:

clientSERVER => clientPROXY => myPROXY => mySERVER

这意味着mySERVER会显示myPROXY的REMOTE_ADDR,而不是客户端的and,并将客户端的实际IP作为HTTP_X_FORWARDED_FOR发送。

为了克服这个问题,我的web服务有一个“可信代理”IP地址列表,如果REMOTE_ADDR来自这些可信IP地址之一,它就会告诉我的web服务实际的IP地址是HTTP_X_FORWARDED_FOR的值。

现在问题出在clientPROXY上了。这意味着(通常) mySERVER会获得具有多个IP地址的HTTP_X_FORWARDED_FOR值。根据HTTP_X_FORWARDED_FOR文档,该值是以逗号分隔的IP地址列表,其中第一个IP是实际真实客户端的IP,其他每个IP地址都是代理的IP地址。

那么,如果HTTP_X_FORWARDED_FOR有多个值,并且我的服务是IP受限的,我是否必须根据我允许的IP列表检查HTTP_X_FORWARDED_FOR的“最后”值,而忽略实际的客户端IP?

我假设在一个系统中,我必须设置允许的IP地址列表,白名单上的IP地址应该是代理的地址,而不是代理后面的IP (因为它可能是某个本地主机IP,并且经常更改)。

HTTP_CLIENT_IP又是什么呢?

EN

回答 7

Stack Overflow用户

发布于 2014-05-13 13:56:59

您可以使用此函数获取正确的客户端IP:

代码语言:javascript
运行
复制
public function getClientIP(){       
     if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)){
            return  $_SERVER["HTTP_X_FORWARDED_FOR"];  
     }else if (array_key_exists('REMOTE_ADDR', $_SERVER)) { 
            return $_SERVER["REMOTE_ADDR"]; 
     }else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
            return $_SERVER["HTTP_CLIENT_IP"]; 
     } 

     return '';
}
票数 35
EN

Stack Overflow用户

发布于 2014-06-18 07:45:43

我喜欢Hrishikesh的回答,对于这个问题,我只对add...because有这样的回答,当使用多个代理时,我们看到一个逗号分隔的字符串,我们发现有必要添加一个分解并获取最终的值,如下所示:

代码语言:javascript
运行
复制
$IParray=array_values(array_filter(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR'])));
return reset($IParray);

array_filter是用来删除空条目的。

票数 24
EN

Stack Overflow用户

发布于 2016-08-03 17:13:50

鉴于最新的httpoxy漏洞,确实需要一个完整的示例,即如何正确使用HTTP_X_FORWARDED_FOR

这里有一个用PHP编写的示例,如何检测客户端IP地址,如果您知道客户端可能位于代理服务器之后,并且知道此代理服务器是可信的。如果您不知道任何受信任的代理,只需使用REMOTE_ADDR

代码语言:javascript
运行
复制
<?php

function get_client_ip ()
{
    // Nothing to do without any reliable information
    if (!isset ($_SERVER['REMOTE_ADDR'])) {
        return NULL;
    }

    // Header that is used by the trusted proxy to refer to
    // the original IP
    $proxy_header = "HTTP_X_FORWARDED_FOR";

    // List of all the proxies that are known to handle 'proxy_header'
    // in known, safe manner
    $trusted_proxies = array ("2001:db8::1", "192.168.50.1");

    if (in_array ($_SERVER['REMOTE_ADDR'], $trusted_proxies)) {

        // Get the IP address of the client behind trusted proxy
        if (array_key_exists ($proxy_header, $_SERVER)) {

            // Header can contain multiple IP-s of proxies that are passed through.
            // Only the IP added by the last proxy (last IP in the list) can be trusted.
            $proxy_list = explode (",", $_SERVER[$proxy_header]);
            $client_ip = trim (end ($proxy_list));

            // Validate just in case
            if (filter_var ($client_ip, FILTER_VALIDATE_IP)) {
                return $client_ip;
            } else {
                // Validation failed - beat the guy who configured the proxy or
                // the guy who created the trusted proxy list?
                // TODO: some error handling to notify about the need of punishment
            }
        }
    }

    // In all other cases, REMOTE_ADDR is the ONLY IP we can trust.
    return $_SERVER['REMOTE_ADDR'];
}

print get_client_ip ();

?>
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11452938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档