Я должен ограничить вход в систему и хочу заблокировать все IP-адреса, если поступают крупномасштабные неудачные попытки. Как я могу добиться этого с помощью приведенного ниже кода? Если приведенный ниже код недостаточно хорош, пожалуйста, сообщите о хорошем руководстве по этому вопросу.
<?php
$throttle = array(1 => 1, 10 => 2, 1000 => 'captcha');
$getfailedq = 'SELECT MAX(attempted) AS attempted FROM failed_logins';
$getfailed = $muc->prepare($getfailedq);
$getfailed->execute();
if ($getfailed->rowCount() > 0) {
$row = $getfailed->fetch(PDO::FETCH_ASSOC);
$latest_attempt = (int) date('U', strtotime($row['attempted']));
$getfailedq = 'SELECT Count(*) AS failed FROM failed_logins WHERE attempted > Date_sub(Now(), INTERVAL 15 minute)';
$getfailed = $muc->prepare($getfailedq);
$getfailed->execute();
if ($getfailed->rowCount() > 0) {
$row = $getfailed->fetch(PDO::FETCH_ASSOC);
$failed_attempts = (int) $row['failed'];
krsort($throttle);
foreach ($throttle as $attempts => $delay) {
if ($failed_attempts > $attempts) {
if (is_numeric($delay)) {
$remaining_delay = time() - $latest_attempt + $delay;
echo 'You must wait ' . $remaining_delay . ' seconds before your next login attempt';
} else {
echo "captcha";
}
break;
}
}
}
}
?>
Это в основном псевдокод, основанный на вашем примере. Вы можете добавить ip
поле к вашему failed_logins
таблица, наряду с созданием новой таблицы с именем blocked_logins
,
<?php
// get users IP address
$ip = $_SERVER['REMOTE_ADDR'];
// find out if user has already been blocked
$getblockedq = 'SELECT ip FROM blocked_logins WHERE ip = :ip';
$getblocked = $muc->prepare($getblockedq);
$getblocked->execute(array(':ip' => $ip));
$total = $getblocked->fetchColumn();
if ($total > 0) {
// user is blocked, do not proceed
}
// find number of failed logins within past 15 mins
$getfailedq = 'SELECT Count(*) AS failed FROM failed_logins WHERE ip = :ip AND attempted > Date_sub(Now(), INTERVAL 15 minute)';
$getfailed = $muc->prepare($getfailedq);
$getfailed->execute(array(':ip' => $ip));
$total = $getfailed->fetchColumn();
if ($total <= 2) {
// looks good, attempt to login
} elseif ($total <= 10) {
// you must wait x seconds...
} elseif ($total <= 1000) {
// display captcha
} else {
// block user
}
Это должно по крайней мере заставить вас начать в правильном направлении.
Других решений пока нет …