Есть еще куча заголовков, которые начинаются с префикса 'HTTP_', где может реально лежать IP-адрес пользователя, но теория гласит, что нельзя довеять таким заголовкам, т.к. он легко подделываются и там так же может лежать, что угодно.
Так как же быть? Откуда брать адрес?
Если то, что написано выше, для вас темный лес, то дальше можете не читать. Вы должны лишь знать, что движок по умолчанию настроен так, что постарается сам, используя свои алгоритмы, определить и записать в базу искомый адрес.
Но если вы понимаете, как сконфигурирован ваш сервер, и знаете, из каких параметров стоит брать IP, то вам могут помочь тонкости конфигурирования вашего приложения.
Общий алгоритм определения IP такой:
1) Задаются элементы массива $_SERVER, из которых точно можно брать IP и/или те, из которых точно нельзя брать IP. Если, в итоге, у нас остается несколько элементов, то мы получим массив IP-адресов, полученный из разных источников.
2) Из массива полученных IP-адресов исключается IP-адрес самого сервера, приватные и зарезервированные IP, а также адреса, которые вы явно можете задать в конфигурации.
3) И если после всех этих операций все равно остается несколько IP, то из массива выбирается первый.
Вот, как эта часть настроек выглядит в конфиг-файле:
// элементы массива $_SERVER, где нужно искать IP-адрес
$config['sys']['ip']['trusted'] = array(
'REMOTE_ADDR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_VIA'
);
// элементы массива $_SERVER, где нужно искать IP-адрес
$config['sys']['ip']['non_trusted'] = array();
// список исключаемых IP-адресов
$config['sys']['ip']['exclude'] = array('127.0.0.1', 'fe80::1', '::1');
// исключить IP-адрес сервера
$config['sys']['ip']['exclude_server'] = true;
// исключать IP частных и зарезервированных сетей
$config['sys']['ip']['exclude_private'] = true;
// IP-адрес по умолчанию, если он так и не был определен
$config['sys']['ip']['default'] = '127.0.0.1';
Реальный пример из жизни.
Очень часто, когда используется связка apache + nginx, заведомо известно, что в $_SERVER['REMOTE_ADDR'] реального IP-адреса пользователя нет и не будет, а адрес надо искать в $_SERVER['HTTP_X_REAL_IP']. Значит, надо убрать 'REMOTE_ADDR' из параметра sys.ip.trusted. Если вы убеждены, что реальный IP всегда будет в 'HTTP_X_REAL_IP' и только в нем – уберите остальные элементы и лишние проверки:$config['sys']['ip']['trusted'] = array('HTTP_X_REAL_IP');
$config['sys']['ip']['non_trusted'] = array();
$config['sys']['ip']['backward'] = true;
$config['sys']['ip']['exclude'] = array();
$config['sys']['ip']['exclude_server'] = false;
$config['sys']['ip']['exclude_private'] = false;
$config['sys']['ip']['default'] = '127.0.0.1';
И, напоследок, две функции для получения IP-адресов посетителя сайта:
F::GetAllUserIp($aTrusted = null, $aNonTrusted = null)
Необязательные параметры aTrusted и aNonTrusted — это списки элементов массива $_SERVER, из которых можно и/или нельзя получать IP-адреса. Если эти параметры не заданы, то они будут браться из конфигурации.
Функция вернет массив всех IP-адресов, которые сможет выцепить.
F::GetUserIp($aTrusted = null, $aNonTrusted = null)
Передаваемые параметры — те же, что и у функции выше.
Функция вернет один IP-адрес — тот, который посчитает настоящим (либо IP-адрес по умолчанию).
1 комментарий