我正在尝试编写一个PHP脚本,用于使用此函数获取客户端的IP地址:
public function getIpAddress() {
$ipAddress = '';
if (! empty($_SERVER['HTTP_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_CLIENT_IP'])) {
// check for shared ISP IP
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} else if (! empty($_SERVER['HTTP_X_FORWARDED_FOR']) && $this->isValidIpAddress($_SERVER['HTTP_CLIENT_IP'])) {
// check for IPs passing through proxy servers
// check if multiple IP addresses are set and take the first one
$ipAddressList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
foreach ($ipAddressList as $ip) {
if ($this->isValidIpAddress($ip)) {
$ipAddress = $ip;
break;
}
}
} else if (! empty($_SERVER['HTTP_X_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_X_FORWARDED'])) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
} else if (! empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && $this->isValidIpAddress($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) {
$ipAddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
} else if (! empty($_SERVER['HTTP_FORWARDED_FOR']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED_FOR'])) {
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
} else if (! empty($_SERVER['HTTP_FORWARDED']) && $this->isValidIpAddress($_SERVER['HTTP_FORWARDED'])) {
$ipAddress = $_SERVER['HTTP_FORWARDED'];
} else if (! empty($_SERVER['REMOTE_ADDR']) && $this->isValidIpAddress($_SERVER['REMOTE_ADDR'])) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
}else{
$ipAddress = 'error';
}
return $ipAddress;
}
我试了很多次,它的工作。但我试图连接到VPN,它检索IPv6而不是IPv4!
这可能是一个正常的情况,但我需要得到该PHP脚本的访问者的IPv4。我在谷歌上搜索了很多关于将IPv6转换为IPv4的信息,我知道它无法转换。
但是我注意到一些IP地理定位服务正在为相同的VPN(在同一设备上)检索IPv4 !例如:canyouseeme.org和api.ipify.org。
这意味着即使IPv6不能转换为IPv4,即使访问者使用IPv6,也可以实现获得IPv4的方法!
我的问题:
- 如果这两个版本之间不可能转换,这些IP地理位置服务如何检索访问者的IPv4 ?
- 如果没有将IPv6转换为IPv4。因此,他们直接检索IPv4,而不接触IPv6。但是,如果$_SERVER不包含IPv4,他们如何做到这一点呢?
除此之外,我注意到当我访问whatismyipaddress.com时,他们首先检索了IPv6,然后它开始加载IPv4字段旁边,然后他们检索了它!
注意:所有这些站点都检索到相同的IPv4。
谢谢。
只要从你的DNS名称中删除AAAA记录(或者在你的webservrr中禁用ipv6 -这可能会引入延迟,因为浏览器应该更喜欢ipv6),然后,然而,没有ipv4的人不能再访问你的服务。正如@MagnusEriksson所说:"与其与未来抗争,不如修复你的应用程序,让它也能与IPv6一起工作,这不是更好吗?">
另外,请注意,如果ip地址对你来说很重要,那么http报头很容易被客户端欺骗(即,不要相信用户提供的数据)或代理服务器可能提供RFC1918中定义的私有ip。你应该只考虑/使用你知道可信代理在你的服务器前面使用的标头——在所有其他情况下,你不能信任用户提供的标头。
如果你正在使用apache,你可能想检查是否有任何IPv6绑定或虚拟主机。其他web服务器也会有类似的设置
如果你没有访问web服务器配置,你可以看看是否有一个选项禁用IPv6在你的webhost面板
也可以是客户端控制的,即当您使用VPN连接时,则为该网络接口(或隧道)启用IPv6。在这种情况下,你不能强迫访问者在他们的设备/路由器上禁用IPv6,但你可以尝试在你的终端上禁用它。不像HTTPS无处不在,只接受端口443或什么都不接受,我不认为IP地址处于只能接受IPv6而不退回到IPv4的阶段,所以这个建议应该是安全的