【发布时间】:2016-11-11 13:49:51
【问题描述】:
这里有一些获取用户IP的理论
Theory1:如果您不使用负载均衡器,请使用REMOTE_ADDR。如果您使用负载均衡器,请使用它使用的任何东西。在 99% 的情况下,这似乎是 HTTP_X_FORWARDED_FOR。所以:
function get_ip_address(){
$id = '';
if (isset($_SERVER['REMOTE_ADDR']))
$ip = $_SERVER['REMOTE_ADDR'];
else if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
else
$ip = 'UNKNOWN';
return $ip;
}
Theory2:还有一些其他的 HTTP 标头信息(即$_SERVER['HTTP_...]) 可能包含 IP。所以:
function get_ip_address(){
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
if (array_key_exists($key, $_SERVER) === true){
foreach (explode(',', $_SERVER[$key]) as $ip){
$ip = trim($ip); // just to be safe
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
return $ip;
}
}
}
}
}
Theory3:同时存储$_SERVER['HTTP_...] 和$_SERVER['REMOTE_ADDR'] 之一。所以有两个变量:
function get_ip_address(){
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key){
if (array_key_exists($key, $_SERVER) === true){
foreach (explode(',', $_SERVER[$key]) as $ip2){
$ip2 = trim($ip2); // just to be safe
if (filter_var($ip2, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
$ip1 = $_SERVER['REMOTE_ADDR'];
return array($ip2, ip1);
}
}
}
}
}
老实说,我有点困惑。我需要多少列(在数据库中)来存储用户的IP?我的意思是我应该同时存储REMOTE_ADDR 和HTTP_... 吗?还是只是其中之一?
实际上,我有一个查询,它在数据库中加载的每个页面插入用户的 IP。因此,每次加载页面之前都会执行该查询。当然,INSERT 查询(每次针对每个请求和每个用户) 都是有成本的。所以我不希望它没用。我的意思是我想存储一个正确/真实的 IP,或者至少我想做最好的工作来检测用户的 IP *。
* 当用户使用像 HSS 这样的代理时,检测他是不可能的。这就是为什么我说“至少”。
好吧,哪个理论最好?
【问题讨论】:
-
你只需要一个。您不应该真正依赖 HTTP 标头,因为它们可以在客户端上更改。如果您信任这些信息,即如果连接 IP
REMOTE_ADDR是受信任的负载均衡器或反向代理,则您应该只使用这些HTTP_X_FORWARDED_...(和任何其他)变量中的任何一个。 -
您也可以将网络服务器配置为自动将
X-FORWARDED-FOR放入REMOTE-ADDRESS,这样您就不必在每个脚本中都这样做了。 -
您似乎是从数据库负载/性能方面提出这个问题,而不是询问 IP 地址的最准确来源是什么。如果您真的只关心数据库方面,存储一两个之间的差异可以忽略不计。
-
@devlincarnate 没有数据库不是我的主题。我想知道如何获取真实IP。
-
@Barmar 我不熟悉网络服务器配置。所以我可以通过 PHP 做到这一点。我只是想知道我应该存储 both
REMOTE-ADDRESS和X-FORWARDED-FOR还是 eitherREMOTE-ADDRESS或X-FORWARDED-FOR?
标签: php database security http ip