Как сужать попытки входа в систему – PHP и MySQL и CodeIgniter

Я хотел бы иметь возможность затормозить попытки входа на основе неудачных попыток, но у меня возникли некоторые вопросы.

Должен ли я использовать MySQL? (читайте, что он может напрягать БД)
Должен ли я дросселировать пользователя и общесистемную или просто общесистемную? (чтобы остановить обычных людей от угадывания паролей)
Как рассчитать мой порог? (поэтому он автоматически адаптируется к изменениям / росту)
Как получить этот порог? Запрос / вычисление при каждом сбое или хранении в кеше?
Что я должен использовать для дросселирования? (прочитайте ответ, что sleep () может привести к напряжению сервера)

У кого-нибудь есть образец кода?

Я совершенно новый, поэтому я ценю помощь! благодаря

Я внедрил механизм дросселирования слабого человека в phunction, используя только APC, вот как я его использую:

// allow 60 requests every 30 seconds // each request counts as 1 (expensive operations can use higher values) // keep track of IPs by REMOTE_ADDR (ignore others) $throttle = ph()->Throttle($ttl = 30, $exit = 60, $count = 1, $proxy = false); if ($throttle === true) { // IP exceded 30 requests in the last 60 seconds, die() here } else { // $throttle is a float // number of requests in the last 30 seconds / 30 seconds /* 1 req / 30 = 0,033 sec 5 req / 30 = 0,166 sec 10 req / 30 = 0,333 sec 15 req / 30 = 0,5 sec 20 req / 30 = 0,666 sec 25 req / 30 = 0,833 sec 30 req / 30 = 1 sec */ usleep(intval(floatval($throttle) * 1000000)); } 

Я использую это на своем Front-Controller и передаю значение методу маршрутизации, но это уже другая история.

Суть в том, что, если вы используете APC, вы можете хранить вещи очень быстро в памяти и с небольшим объемом памяти, потому что APC следует методологии FILO. Если вам нужен более высокий тайм-аут, вы можете подумать о том, чтобы использовать что-то, что не основано на памяти.

BTW: MySQL поддерживает таблицы с движком MEMORY.


Проблема со sleep() :

Типичный веб-сервер Apache с PHP, установленный в качестве модуля, будет потреблять около 10 МБ оперативной памяти на один экземпляр, чтобы избежать превышения вашего доступного бара, есть некоторые настройки Apache, которые вы можете настроить для ограничения максимального количества экземпляров, которые Apache может запустить.

Проблема заключается в том, когда вы sleep() , этот экземпляр все еще активен и с достаточным количеством запросов может в конечном итоге съесть все доступные слоты для запуска новых серверов, тем самым делая ваш веб-сайт недоступным до тех пор, пока не будут выполнены некоторые ожидающие запроса запросы.

Невозможно преодолеть это из PHP AFAIK, так что в итоге это зависит от вас.


Принцип тот же для системного дросселирования:

 function systemWide($ttl = 86400, $exit = 360) { if (extension_loaded('apc') === true) { $key = array(__FUNCTION__); if (apc_exists(__FUNCTION__) !== true) { apc_store(__FUNCTION__, 0, $ttl); } $result = apc_inc(__FUNCTION__, 1); if ($result < $exit) { return ($result / $ttl); } return true; } return false; } 

Лог ошибок входа в систему в таблице выглядит следующим образом:

 FailedLogins id timestamp ip 

Каждый раз, когда пользователь пытается войти в систему, вы проверяете, имеет ли IP-адрес пользователя X число неудачных попыток входа в систему за последние Y секунд.

Если пользователь потерял X раз в течение Y секунд, вы представляете сообщение об ошибке или CAPTCHA.

База данных MySQL может обрабатывать тоны запросов / сек, поэтому вам не нужно беспокоиться о шеих бутылок, если у вас нет тысяч пользователей.

Вы также можете использовать sleep () ПРИМЕЧАНИЕ: PHP обрабатывает больше пользователей, чем ASP.NET – так снова. Если у вас нет тысяч пользователей, вы можете использовать методы сна, без шейки бутылки.

Как я обычно это делаю, это сохранение попыток входа (IP, идентификатор пользователя и временная метка). Храните его в таблице и перезагружайте таблицу, когда вам хочется (при определенном размере или времени суток). Если идентификатор пользователя + IP имеет более «количество попыток входа в систему» ​​в «определенное время», перенаправляйте пользователя на страницу, которая сообщает пользователю, что он / она использовал для многих попыток, и не сможет войти в систему следующие 15 минут (или как вам кажется). Немного «Windows», как я предполагаю, но это работает как шарм 🙂