2013-05-17 51 views

回答

1

你想要的X-Forwarded-For头,但幼稚的做法是错误的,因为X-Forwarded-For can contain multiple IP addresses,代表代理途中。

这里就是你真正想要的(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'];

1

您是否尝试过让使用PHP的IP,这样的:

if ($_SERVER["HTTP_X_FORWARDED_FOR"]) { 
    $ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
} 
else { 
    $ip = $_SERVER["REMOTE_ADDR"]; 
} 
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; 
}