如果 Drupal (7.17) 网站落后于负载均衡器,是否有任何解决方法可以获取实际用户 IP ?它总是返回我负载均衡器的 IP 地址。
问问题
3112 次
3 回答
2
Drupal 有函数 ip_address()
function ip_address() {
$ip_address = &drupal_static(__FUNCTION__);
if (!isset($ip_address)) {
$ip_address = $_SERVER['REMOTE_ADDR'];
if (variable_get('reverse_proxy', 0)) {
$reverse_proxy_header = variable_get('reverse_proxy_header', 'HTTP_X_FORWARDED_FOR');
if (!empty($_SERVER[$reverse_proxy_header])) {
// If an array of known reverse proxy IPs is provided, then trust
// the XFF header if request really comes from one of them.
$reverse_proxy_addresses = variable_get('reverse_proxy_addresses', array());
// Turn XFF header into an array.
$forwarded = explode(',', $_SERVER[$reverse_proxy_header]);
// Trim the forwarded IPs; they may have been delimited by commas and spaces.
$forwarded = array_map('trim', $forwarded);
// Tack direct client IP onto end of forwarded array.
$forwarded[] = $ip_address;
// Eliminate all trusted IPs.
$untrusted = array_diff($forwarded, $reverse_proxy_addresses);
// The right-most IP is the most specific we can trust.
$ip_address = array_pop($untrusted);
}
}
}
return $ip_address;
}
于 2013-12-13T15:11:02.430 回答
1
您是否尝试过使用 PHP 获取 IP,如下所示:
if ($_SERVER["HTTP_X_FORWARDED_FOR"]) {
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
}
else {
$ip = $_SERVER["REMOTE_ADDR"];
}
于 2013-05-18T09:05:56.043 回答
1
您确实需要X-Forwarded-For
标头,但天真的方法是错误的,因为X-Forwarded-For
它可以包含多个 IP 地址,代表途中的代理。
这是您真正想要的(Ideone):
<?php
// Don't use this function directly to parse arbitrary headers, since it
// assumes that the headers you're passing in are associated with the
// current $_SERVER variable.
function get_client($headers) {
if (isset($headers['HTTP_X_FORWARDED_FOR'])) {
return explode(', ', $headers['HTTP_X_FORWARDED_FOR'])[0];
}
else {
return $_SERVER['REMOTE_ADDR'];
}
}
// You'd want to do this on a server, but not on ideone:
// $headers = getallheaders();
$headers = array('HTTP_X_FORWARDED_FOR' => 'client, proxy1, proxy2');
echo "Client 1: " . get_client($headers) . "\n";
$headers = array('HTTP_X_FORWARDED_FOR' => 'client');
echo "Client 2: " . get_client($headers) . "\n";
// $_SERVER['REMOTE_ADDR'] is blank on ideone but works on servers:
$headers = array();
echo "Client 3: " . get_client($headers) . "\n";
?>
另请注意,X-Forwarded-For
它很容易被欺骗,因此您不应仅在安全上下文中依赖它。例如,禁止列表的正确方法还需要了解$_SERVER['REMOTE_ADDR'];
。
于 2013-05-18T13:18:21.587 回答