Будет ли значение набора $ SERVER ['HTTP CLIENT IP'] пустой строкой?
у меня есть простой скрипт, который определяет IP-адрес пользователя:
function GetIp(){
if (!empty($_SERVER['HTTP_CLIENT_IP']))
//check ip from share internet
{
$ip=$_SERVER['HTTP_CLIENT_IP'];
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
//to check ip is pass from proxy
{
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
}
else
{
$ip=$_SERVER['REMOTE_ADDR'];
}
return $ip;
}
теперь в Сети где-то я видел, как кто-то использует этот скрипт:
if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '')
$Ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '')
$Ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '')
$Ip = $_SERVER['REMOTE_ADDR'];
мне было интересно, сломана ли моя реализация.. Нужно ли проверять, если значение $_SERVER['HTTP_CLIENT_IP']
, $_SERVER['HTTP_X_FORWARDED_FOR']
или $_SERVER['REMOTE_ADDR']
пусто? Или в этом действительно нет необходимости?
4 ответов
Если причина, по которой вы хотите узнать IP-адрес клиента, действительно важна, к черту все это.
ни один из этих значений заголовка можно свободно подделать.
REMOTE_ADDR
является единственной действительно надежной информацией, так как она передается вам вашим веб-сервером, который обрабатывает запрос. Это может быть теоретически также фальсифицированных, но это намного сложнее, чем подделка значения заголовка и совершенно другого класса нападения.
есть исключения в очень, очень конкретных средах хостинга за обратными прокси. В этих случаях человек, администрирующий этот прокси, сможет сказать, какое значение заголовка вам нужно проверить.
из класса запроса Коханаса:
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
// Format: "X-Forwarded-For: client1, proxy1, proxy2"
$client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['HTTP_CLIENT_IP'])
AND isset($_SERVER['REMOTE_ADDR'])
AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies))
{
// Use the forwarded IP address, typically set when the
// client is using a proxy server.
$client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']);
Request::$client_ip = array_shift($client_ips);
unset($client_ips);
}
elseif (isset($_SERVER['REMOTE_ADDR']))
{
// The remote IP address
Request::$client_ip = $_SERVER['REMOTE_ADDR'];
}
Это почти так же хорошо, как и получается. Обратите внимание на Request::$trusted_proxies
массив и что ваш $ip
var это Request::$client_ip
в этом случае.
не проверятьHTTP_*
заголовки для IP клиента, если вы специально не знаете, что ваше приложение настроено за обратным прокси. Безоговорочное доверие значениям этих заголовков позволит пользователям подделать свой IP-адрес.
только $_SERVER
поле, содержащее надежное значение REMOTE_ADDR
.
эти две вещи практически одинаковые.. В найденном скрипте автор просто проверяет, установлен ли элемент в массиве, прежде чем проверять, что он не пуст.
в отношении использования empty()
- функция вместо сравнения, проверьте http://php.net/empty. Поскольку вы имеете дело с переменной, заданной средой, а не пользовательским вводом, не имеет значения, какой из двух вариантов вы выбираете. Так что ваш сценарий должен быть идеально штраф в размере