如何正确使用HTTP_X_FORWARDED_FOR?

2022-08-30 11:52:43

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

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

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

clientSERVER => clientPROXY => myPROXY => mySERVER

然后,这意味着 mySERVER 显示 myPROXY 而不是客户端的 ip,并将客户端的实际 IP 作为 发送。REMOTE_ADDRHTTP_X_FORWARDED_FOR

为了克服这个问题,我的Web服务有一个“受信任的代理”IP地址列表,如果来自这些受信任的IP地址之一,那么它会告诉我的Web服务,实际的IP地址是的值。REMOTE_ADDRHTTP_X_FORWARDED_FOR

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

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

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

而呢?HTTP_CLIENT_IP


答案 1

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

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

答案 2

我喜欢Hrishikesh的答案,我只有这个补充......因为我们看到在沿途使用多个代理时会遇到一个逗号分隔的字符串,所以我们发现有必要添加一个分解并获取最终值,如下所示:

$IParray=array_values(array_filter(explode(',',$_SERVER['HTTP_X_FORWARDED_FOR'])));
return reset($IParray);

array_filter在那里删除空条目。


推荐