我是PHP的新手,我有一个任务来处理地理定位。
我想在我的php应用程序中获取client_ip。该应用程序部署在AWS上,具有2个负载均衡器和apache Web服务器。
我试过以下:
if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} elseif (array_key_exists('HTTP_X_FORWARDED', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
} elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (array_key_exists('HTTP_FORWARDED_FOR', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
} elseif (array_key_exists('HTTP_FORWARDED', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_FORWARDED'];
} elseif (array_key_exists('REMOTE_ADDR', $_SERVER)) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
} else {
$ipAddress = '';
}
我认为它会起作用,但事实并非如此。然后我查看了phpinfo并发现了以下内容:
在Headers
,X-Forwarded-For
设定为10.1.29.16,
$_SERVER['HTTP_X_FORWARDED_FOR']
设定为10.1.29.16和
$_SERVER['REMOTE_ADDR']
是172.17.7.173。
所有都是内部IP地址。
任何人都可以指导我,我怎样才能找到真正客户的IP地址?
PS:它是一个Symfony 4应用程序。
您正在以错误的顺序检查标头。首先检查FORWARDED_FOR类型。您需要检查实例前面的服务器(负载平衡器等)的文档,以了解要引用的标头。 HTTP_X_FORWARDED_FOR
可能是最常见的。你是盲目检查任何东西。
您假设标头包含单个值。如果有一系列服务器,那么每个服务器都会添加其地址。一个例子是带有ALB的Cloudfront。
标题$_SERVER['REMOTE_ADDR']
不可靠,不应该被信任。实际上,除非您控制整个链(缓存,负载平衡等),否则不应信任任何标头。锻造这些价值非常容易。