// request获取ip
$request->getClientIp();
$request->ip();
举例:公司网络使用拨号或者代理模式访问我们的业务系统此时$request->getClientIp() 和 $request->ip() 只能获取到访客的公网出口统一的ip地址,拿不到真实的访客ip
解决关键词 HTTP_X_FORWARDED_FOR
如果一个 HTTP 请求到达服务器之前,经过了三个代理 Proxy1、Proxy2、Proxy3,IP 分别为 IP1、IP2、IP3,用户真实 IP 为 IP0,那么按照 XFF 标准,服务端最终会收到以下信息:
X-Forwarded-For: IP0, IP1, IP2
代码片 解觉方案
.
function getRealIp()
{
$ip = data_get($_SERVER, 'HTTP_X_FORWARDED_FOR') ?:#获取用户ip
if (strstr($ip, ",")) {#如果经过代理有多个ip,循环处理
$ip_arr = explode(',', $ip);
foreach ($ip_arr as $ip) {
$ipint = sprintf('%u', ip2long($ip));#ip2long — 将 IPV4 的字符串互联网协议转换成长整型数字
if ($ipint >= 0 && $ipint <= 50331647 || // {"0.0.0.0","2.255.255.255"},
$ipint >= 167772160 && $ipint <= 184549375 || // {"10.0.0.0","10.255.255.255"},
$ipint >= 2130706432 && $ipint <= 2147483647 || // {"127.0.0.0","127.255.255.255"},
$ipint >= 2851995648 && $ipint <= 2852061183 || // {"169.254.0.0","169.254.255.255"}
$ipint >= 2886729728 && $ipint <= 2887778303 || // {"172.16.0.0","172.31.255.255"},
$ipint >= 3221225984 && $ipint <= 3221226239 || // {"192.0.2.0","192.0.2.255"},
$ipint >= 3232235520 && $ipint <= 3232301055 || // {"192.168.0.0","192.168.255.255"},
$ipint >= 4294967040 && $ipint <= 4294967295 // {"255.255.255.0","255.255.255.255"}
){
continue;
}else{
break;
}
}
}
return trim($ip);
}
总结:HTTP_X_FORWARDED_FOR可获取真实ip和代理ip,此方法框架通用