基本上,我有一个带阻塞系统的登录系统。 阻止用户使用超过5次尝试,如果他仍然尝试,尝试次数将增加。
要删除它,我这样做:
"DELETE FROM login_attempts WHERE date < DATE_SUB(NOW(), INTERVAL :time) AND ip_address = :ip"
:时间=间隔日期
示例:
if ($fetch['attempts'] < 6)
{
$time = "10 MINUTE";
}
else if ($fetch['attempts'] < 10)
{
$time = "1 HOUR";
}
else if ($fetch['attempts'] < 21)
{
$time = "1 DAY";
}
else if ($fetch['attempts'] > 21)
{
$time = "14 DAY";
}
基本上我想要做的是,我需要找出,如何告诉玩家他何时会被解锁。
如果我知道他将被解锁的时间量,我怎么能回应时间直到他被解锁?我不想只是回应日期,我需要确切地回复多少天,几小时等等。
我从来没有这样做过,我现在陷入困境。
答案 0 :(得分:2)
您写道:“这些失败将在1天后重置”。然后,不可能达到超过21次失败的尝试,因为在第21次尝试失败时,该帐户被锁定了一天。
我认为你应该只在成功尝试时重置计数器。
话虽如此,让我们回到你的实际问题。您正试图显示该帐户将保持锁定的时间。
我会采取相反的方法:根据失败的尝试次数,计算帐户解锁的日期,然后计算此日期之前的剩余时间。
SELECT COUNT(*) AS failed_count
FROM login_attempts WHERE account_id = :account AND ip_address = :ip
纯SQL中的解决方案:
SELECT
CASE
WHEN COUNT(*) <= 5 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 10 MINUTE)
WHEN COUNT(*) <= 10 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 HOUR)
WHEN COUNT(*) <= 20 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 DAY)
ELSE DATE_ADD(MAX(date_of_attempt), INTERVAL 14 DAY)
END AS unlock_date
FROM login_attempts WHERE account_id = :account AND ip_address = :ip
注意:我将根据您将在应用程序层中维护的规则,从PHP动态构建上述查询。但是坚持这个查询,因为你在一个查询中得到了所有内容,并且如果你有适当的索引它几乎立即运行。
要么在PHP中计算(应该是微不足道的),要么直接在MySQL中计算:
SELECT
TIMEDIFF(
NOW(),
CASE
WHEN COUNT(*) <= 5 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 10 MINUTE)
WHEN COUNT(*) <= 10 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 HOUR)
WHEN COUNT(*) <= 20 THEN DATE_ADD(MAX(date_of_attempt), INTERVAL 1 DAY)
ELSE DATE_ADD(MAX(date_of_attempt), INTERVAL 14 DAY)
END
) AS time_remaining_in_hours
FROM login_attempts WHERE account_id = :account AND ip_address = :ip
答案 1 :(得分:-2)