I. Как добраться IP-адрес пользователя Адрес
public static function getClientIp() { if (getenv('HTTP_CLIENT_IP')) { $ip = getenv('HTTP_CLIENT_IP'); } if (getenv('HTTP_X_REAL_IP')) { $ip = getenv('HTTP_X_REAL_IP'); } elseif (getenv('HTTP_X_FORWARDED_FOR')) { $ip = getenv('HTTP_X_FORWARDED_FOR'); $ips = explode(',', $ip); $ip = $ips[0]; } elseif (getenv('REMOTE_ADDR')) { $ip = getenv('REMOTE_ADDR'); } else { $ip = '0.0.0.0'; } return $ip; }
Будьте осторожны:
Разница между $_SERVER и getenv заключается в том, что getenv не поддерживает PHP, работающий в режиме ISAPI, функция IIS Getenv (“REMOTE_ADDR”) может обычно получать IP-адрес в apache, но в iis это не влияет. Функция $_SERVER [‘REMOTE_ADDR’] может не только успешно получить IP-адрес посетителя в apache, но и быть эффективной в iis.
I. REMOTE_ADDR
Эта переменная получает IP-адрес прямого источника, который ссылается на IP-адрес клиента, который запрашивает адрес напрямую. В случае одного сервера этот IP-адрес является в точности IP-адресом клиента и не может быть подделан. Конечно, не все программы обязательно являются отдельными серверами, например, в случае балансировки нагрузки (например, haproxy или nginx для балансировки нагрузки), этот IP – адрес является IP-адресом машины пересылки, потому что процесс-клиент – > Балансировка нагрузки – > сервер. Это сервер, к которому осуществляется прямой доступ с помощью балансировки нагрузки, а не клиент.
На HTTP_X_FORWARDED_FOR и HTTP_CLIENT_IP На основе “I” невозможно получить IP-адрес клиента с помощью REMOTE_ADDR непосредственно при балансировке нагрузки. Это проблема, которую необходимо решить. Таким образом, балансировка нагрузки и добавляет IP-адрес клиента в HEAD и отправляет его на сервер, чтобы сервер мог получить реальный IP-адрес клиента. Конечно, есть то, что вы называете подделкой. В конце концов, у HEAD есть настраиваемые данные, кроме тех, которые зафиксированы в протоколе.
3. Зачем нам нужно по очереди получать HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR и REMOTE_ADDR, когда мы находим код для получения IP-адреса клиента в Интернете? Основываясь на “I” и “II”, а также на учете универсальности программы, это является причиной для этого. Предположим, вы пишете REMOTE_ADDR непосредственно в своей программе, и однажды вашей программе потребуется выполнить балансировку нагрузки, а затем вам придется ее изменить. Конечно, если вы хотите это сделать, вы также можете просмотреть личные увлечения и сценарии приложений. Вы также можете инкапсулировать метод только для REMOTE_ADDR и изменять его при необходимости.
Вывод:
HTTP_CLIENT_IP: Заголовки доступны, но не являются стандартными, и не обязательно все серверы реализованы.
X-Forwarded-For (XFF): поле заголовка HTTP-запроса, используемое для определения исходного IP-адреса клиента, подключенного к веб-серверу через HTTP-прокси или балансировку нагрузки. Формат: ip клиента, proxy1, proxy2
REMOTE_ADDR: Это надежно. Это последний IP-адрес, с которого можно обменяться рукопожатием с вашим сервером. Это может быть прокси-сервер пользователя или его собственный обратный прокси-сервер.
X-Переадресованный для и X-Реальный IP:
X-Forwarded-For используется для записи информации прокси-сервера. Для каждого уровня прокси-сервера (кроме анонимного прокси-сервера) прокси-сервер добавляет исходный IP-адрес запроса в X-Forwarded-For, в то время как X-Real-IP не имеет соответствующего стандарта, и его значение не фиксировано в разных средах прокси.
Для более подробного обсуждения, пожалуйста, обратитесь к https://www.douban.com/group/topic/27482290./
1. Балансировка нагрузки:
Многие серверы в производственной среде скрыты за узлом балансировки нагрузки. Вы можете получить IP-адрес узла балансировки нагрузки только через REMOTE_ADDR. Как правило, фактический IP-адрес интерфейса будет передаваться через HTTP_CLIENT_IP или HTTP_X_FORWARDED_FДЛЯ двух типов HTTP-заголовков.
Можно доверять тому, что серверная часть снова считывает это значение, потому что это то, что сообщает вам узел балансировки нагрузки, а не клиент. Но когда ваш сервер напрямую открыт для клиента, не доверяйте этим двум методам чтения, просто прочитайте REMOTE_ADDR.
2. Ситуация с CDN:
Поэтому, чтобы получить IP-адрес пользователя, мы должны перехватить первый действительный IP-адрес (неизвестный) http_x_forwarded_for.
В многоуровневом прокси-сервере он похож на cdn.
Будьте осторожны:
Будь то REMOTE_ADDR или HTTP_FORWARDED_FOR, эти сообщения заголовка могут быть недоступны, поскольку разные браузеры и сетевые устройства могут отправлять разные сообщения IP-заголовка.
II. Предотвращение атак с использованием IP-адресов
Добавьте следующий код для предотвращения атак с использованием IP-адресов:
// IP Address Validation to Prevent IP Injection Attacks $long = sprintf("%u", ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
Как правило, после получения IP-адреса обновите код базы данных, например:. get_client_ip(). “‘где…”, и если полученный IP-адрес: xxxx.xxxx.xxxx’; удалить из t_users; – – подставляя параметр, оператор SQL становится: “обновить t_set; удалить из t_users; — где…
Поэтому после получения IP-адреса мы должны использовать регуляризацию для проверки действительности IP-адреса. Кроме того, мы должны использовать параметризованную команду SQL.
Анализ:
Функция sprintf () записывает отформатированную строку в переменную. *% U – десятичное число без знака (больше или равно 0)
int ip2long ( строка $ip_адрес ):
Возвращает преобразованное количество IP-адресов или значение FALSE, если ip_address неверен.
Будьте осторожны:
Примеры иллюстрируют функцию печати переведенного адреса с помощью функции printf () в PHP4 и PHP5:
1. Поскольку целочисленный тип PHP является символическим, и существует множество IP-адресов, которые вызывают отрицательные числа в 32-разрядных системах, вам необходимо использовать “% u” для преобразования строки, полученной с помощью sprintf () или printf (), для представления IP-адреса без знака.
2. ip2long () вернет FALSE на IP 255.255.255.255.255, версия PHP 5.0.2. После ремонта PHP 5.0.3 вернет – 1 (так же, как PHP 4).
3. Механизм защиты от щеток
Для получения IP-адреса мы можем выполнить некоторые операции, защищающие кисти:
//ip limit $ip = getClientIp(); $ipKey = "activity_key_{$ip}"; if (!frequencyCheckWithTimesInCache($ipKey, $duration, $limitTimes)) { return false; } return true;
// Limit id, requesting up to $times in the $second time public static function frequencyCheckWithTimesInCache($id, $second, $times) { $value = Yii::app()->cache->get($id); if (!$value) { $data[] = time(); Yii::app()->cache->set($id, json_encode($data), $second); return true; } $data = json_decode($value, true); if (count($data) + 1 <= $times) { $data[] = time(); Yii::app()->cache->set($id, json_encode($data), $second); return true; } if (time() - $data[0] > $second) { array_shift($data); $data[] = time(); Yii::app()->cache->set($id, json_encode($data), $second); return true; } return false; }
Приведите пример:
Ограничьте количество запросов не более чем 50 в час
if (!frequencyCheckWithTimesInCache('times_uid_' . $uid, 3600, 50)) { Return'Too frequent requests'; }
Обновление Щетки Ограниченное Количество Оборудования:
// Equipment number A device number can only be drawn three times at most. if(! empty($deviceId)){ $deviceUseChance = Yii::app()->db->createCommand() ->select('count(id)')->from('activity00167_log') ->where('device_id=:deviceId',['deviceId'=>$deviceId]) ->queryScalar(); $deviceChance = 3 - $deviceUseChance; }
Для получения IP-адресов мы также можем анализировать географическое местоположение пользователей в больших данных, например, выполнять некоторые точные работы по размещению.
резюме
Выше приведен пример кода PHP для получения реального IP-адреса пользователя и механизма защиты от кисти, введенного Xiaobian. Я надеюсь, что это будет полезно для вас. Если у вас есть какие-либо вопросы, пожалуйста, оставьте мне сообщение, и Сяобянь ответит вам вовремя. Большое вам спасибо за вашу поддержку в развитии peer.