如何从访客得到真实的IP?
我正在使用这个PHP代码来获取访问者的IP地址:
<?php echo $_SERVER['REMOTE_ADDR']; ?>
但是, 当使用代理时 ,我无法从访问者那里得到真实的IP地址。 在这种情况下,有没有办法获得访问者的IP地址?
试试这个PHP代码。
<?PHP function getUserIP() { $client = @$_SERVER['HTTP_CLIENT_IP']; $forward = @$_SERVER['HTTP_X_FORWARDED_FOR']; $remote = $_SERVER['REMOTE_ADDR']; if(filter_var($client, FILTER_VALIDATE_IP)) { $ip = $client; } elseif(filter_var($forward, FILTER_VALIDATE_IP)) { $ip = $forward; } else { $ip = $remote; } return $ip; } $user_ip = getUserIP(); echo $user_ip; // Output IP address [Ex: 177.87.193.134] ?>
这是我见过的最常用的技术:
function getUserIP() { if( array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER) && !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ) { if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',')>0) { $addr = explode(",",$_SERVER['HTTP_X_FORWARDED_FOR']); return trim($addr[0]); } else { return $_SERVER['HTTP_X_FORWARDED_FOR']; } } else { return $_SERVER['REMOTE_ADDR']; } }
请注意,它并不能保证你将永远得到正确的用户IP,因为有很多方法来隐藏它。
这是我的做法:
function getRealUserIp(){ switch(true){ case (!empty($_SERVER['HTTP_X_REAL_IP'])) : return $_SERVER['HTTP_X_REAL_IP']; case (!empty($_SERVER['HTTP_CLIENT_IP'])) : return $_SERVER['HTTP_CLIENT_IP']; case (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) : return $_SERVER['HTTP_X_FORWARDED_FOR']; default : return $_SERVER['REMOTE_ADDR']; } }
如何使用:
$ip = getRealUserIp();
代理可能会发送一个HTTP_X_FORWARDED_FOR
头,但即使这是可选的。
另外请记住,访问者可能共享IP地址; 大学networking,大公司和第三世界/低预算的互联网服务提供商倾向于分享许多用户的IP。
申请这个代码获得ipaddress:
if (getenv('HTTP_X_FORWARDED_FOR')) { $pipaddress = getenv('HTTP_X_FORWARDED_FOR'); $ipaddress = getenv('REMOTE_ADDR'); echo "Your Proxy IP address is : ".$pipaddress. "(via $ipaddress)" ; } else { $ipaddress = getenv('REMOTE_ADDR'); echo "Your IP address is : $ipaddress"; } ------------------------------------------------------------------------
是的, $_SERVER["HTTP_X_FORWARDED_FOR"]
是我在我的nginx服务器上的代理下看到我的IP。
但是最好的办法是在代理下的页面上运行phpinfo()
,这样你就可以查看所有可用的variables,看看真正的ip是什么。
<?php function getrealip() { if (isset($_SERVER)){ if(isset($_SERVER["HTTP_X_FORWARDED_FOR"])){ $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; if(strpos($ip,",")){ $exp_ip = explode(",",$ip); $ip = $exp_ip[0]; } }else if(isset($_SERVER["HTTP_CLIENT_IP"])){ $ip = $_SERVER["HTTP_CLIENT_IP"]; }else{ $ip = $_SERVER["REMOTE_ADDR"]; } }else{ if(getenv('HTTP_X_FORWARDED_FOR')){ $ip = getenv('HTTP_X_FORWARDED_FOR'); if(strpos($ip,",")){ $exp_ip=explode(",",$ip); $ip = $exp_ip[0]; } }else if(getenv('HTTP_CLIENT_IP')){ $ip = getenv('HTTP_CLIENT_IP'); }else { $ip = getenv('REMOTE_ADDR'); } } return $ip; } $MyipAddress = getrealip(); echo $MyipAddress; // IP: 58.97.178.57 ?>
这是输出
//获取客户端IP地址的函数
function get_client_ip() { $ipaddress = ''; if (getenv('HTTP_CLIENT_IP')) $ipaddress = getenv('HTTP_CLIENT_IP'); else if(getenv('HTTP_X_FORWARDED_FOR')) $ipaddress = getenv('HTTP_X_FORWARDED_FOR'); else if(getenv('HTTP_X_FORWARDED')) $ipaddress = getenv('HTTP_X_FORWARDED'); else if(getenv('HTTP_FORWARDED_FOR')) $ipaddress = getenv('HTTP_FORWARDED_FOR'); else if(getenv('HTTP_FORWARDED')) $ipaddress = getenv('HTTP_FORWARDED'); else if(getenv('REMOTE_ADDR')) $ipaddress = getenv('REMOTE_ADDR'); else $ipaddress = 'UNKNOWN'; return $ipaddress; }
这是我的function。
好处:
- 在$ _SERVER不可用的情况下工作。
- 过滤私有和/或保留的IP;
- 在X_FORWARDED_FOR中处理所有转发的IP
- 与CloudFlare兼容
- 如果找不到有效的IP,可以设置默认值!
- 简单而简单!
/** * Get real user ip * * Usage sample: * GetRealUserIp(); * GetRealUserIp('ERROR',FILTER_FLAG_NO_RES_RANGE); * * @param string $default default return value if no valid ip found * @param int $filter_options filter options. default is FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE * * @return string real user ip */ function GetRealUserIp($default = NULL, $filter_options = 12582912) { $HTTP_X_FORWARDED_FOR = isset($_SERVER)? $_SERVER["HTTP_X_FORWARDED_FOR"]:getenv('HTTP_X_FORWARDED_FOR'); $HTTP_CLIENT_IP = isset($_SERVER)?$_SERVER["HTTP_CLIENT_IP"]:getenv('HTTP_CLIENT_IP'); $HTTP_CF_CONNECTING_IP = isset($_SERVER)?$_SERVER["HTTP_CF_CONNECTING_IP"]:getenv('HTTP_CF_CONNECTING_IP'); $REMOTE_ADDR = isset($_SERVER)?$_SERVER["REMOTE_ADDR"]:getenv('REMOTE_ADDR'); $all_ips = explode(",", "$HTTP_X_FORWARDED_FOR,$HTTP_CLIENT_IP,$HTTP_CF_CONNECTING_IP,$REMOTE_ADDR"); foreach ($all_ips as $ip) { if ($ip = filter_var($ip, FILTER_VALIDATE_IP, $filter_options)) break; } return $ip?$ip:$default; }
如果代理是您信任的,您可以尝试:(假设代理IP是151.101.2.10
)
<?php $trustProxyIPs = ['151.101.2.10']; $clientIP = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : NULL; if (in_array($clientIP, $trustProxyIPs)) { $headers = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR']; foreach ($headers as $key => $header) { if (isset($_SERVER[$header]) && filter_var($_SERVER[$header], FILTER_VALIDATE_IP)) { $clientIP = $_SERVER[$header]; break; } } } echo $clientIP;
这将防止直接请求的客户伪造的转发头,并通过信任的代理获得真实的IP。
这适用于Windows和Linux! 不要紧,如果它是本地或在线..
function getIP() { $ip = $_SERVER['SERVER_ADDR']; if (PHP_OS == 'WINNT'){ $ip = getHostByName(getHostName()); } if (PHP_OS == 'Linux'){ $command="/sbin/ifconfig"; exec($command, $output); // var_dump($output); $pattern = '/inet addr:?([^ ]+)/'; $ip = array(); foreach ($output as $key => $subject) { $result = preg_match_all($pattern, $subject, $subpattern); if ($result == 1) { if ($subpattern[1][0] != "127.0.0.1") $ip = $subpattern[1][0]; } //var_dump($subpattern); } } return $ip; }