如果透過 PHP 的 $_SERVER['REMOTE_ADDR'] 抓取用戶 IP,經常會遇到一個狀況,就是用戶可能有透過 proxy,所以就會抓錯。
透過 proxy 時,會多帶一個 X-Forwarded-For 的 header,表達是為哪個 IP 做 forward 的動作,所以需要看這個 header 來決定。
但是,如果是 NAT 時,又要以他的 Public IP 作為遠端 IP,不然看到一大堆 192.168.x.x 也不太有意義。
下面的 php function 可以幫忙做這件事情,判斷是否有 X-Forwarded-For,若有,還會過濾看是否為 Private IP,簡單說,呼叫這個參數就可以取得用戶的 IP 囉!!! (當然有時候這種事情不是絕對的,但是已經具有代表性囉!
function getRemoteIP() {
if ( function_exists( 'apache_request_headers' ) ) {
$headers = apache_request_headers();
} else {
$headers = $_SERVER;
}
//Get the forwarded IP if it exists
if ( array_key_exists( 'X-Forwarded-For', $headers ) && filter_var( $headers['X-Forwarded-For'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) ) {
$the_ip = $headers['X-Forwarded-For'];
} elseif ( array_key_exists( 'HTTP_X_FORWARDED_FOR', $headers ) && filter_var( $headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE )) {
$the_ip = $headers['HTTP_X_FORWARDED_FOR'];
} else {
$the_ip = filter_var( $_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP );
}
return $the_ip;
}