Будет ли значение набора $ 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. Поскольку вы имеете дело с переменной, заданной средой, а не пользовательским вводом, не имеет значения, какой из двух вариантов вы выбираете. Так что ваш сценарий должен быть идеально штраф в размере