mysql - 正确执行临时禁令

标签 mysql postgresql

好的,您有登录表单,如果用户输入的密码/用户错误,您希望禁止用户 5 分钟。 用户可以连续尝试几次直到被禁止。

LOGIN_FAILS 表:

  • id PK,串行/auto_increment
  • ipaddress int/text/whatever you prefer
  • 添加了 DATETIME/TIMESTAMP

SQL:

SELECT IF(COUNT(id) < 3, 'false', 'true') AS is_banned FROM LOGIN_FAILS WHERE ipaddress='1.2.3.4' AND added BETWEEN (NOW() - INTERVAL '5 minutes') AND NOW();

这可以可视化为

禁止检查时间 block :#####

失败:1,2,3

失败设置为时间范围:

Time ->
========1==2=3==========
========######==========

现在您可以连续重试一次:

========1######=========

现在您可以连续重试两次:

========1==2######======

但正确的做法是保持这个时间 block 5 分钟

========######==========

现在你可以连续重试三次

========1==2=3######====
        ^^^^^^ Ignored

但是您不想使用当前时间作为 block (0:00-0:05、0:05-0:10 等),因为如果禁令发生在 0:04,则下一个禁令检查时间 block 为 0 :05(= 仅 1 分钟禁令)。

那么必须对给定的 SQL 语句添加/修改什么,以便用户始终可以连续尝试 N 次,然后暂时禁止 X 分钟?

编辑

有点像

SELECT
  IF(COUNT(id) < 3, 'false', 'true') AS is_banned
FROM 
  LOGIN_FAILS
WHERE 
  ipaddress='1.2.3.4' AND
  added 
  BETWEEN
  (
    SELECT
      MIN(added) AS min
    FROM
      LOGIN_FAILS
    WHERE
      ipaddress='1.2.3.4' AND
      added <= (NOW() - INTERVAL 5 minutes)
    ORDER BY
      added
    LIMIT 3
  )
  AND
  NOW()

最佳答案

正如我从你的长问题中了解到的那样,你需要知道一个 ip 是否会因为它在上次 $time_for_ban_try 内的失败登录尝试而被禁止。那么你可以尝试以下 -

$time_for_ban_try = 10;//分钟,例如

$sql = "SELECT IF(COUNT(id) < 3, 'false', 'true') AS is_banned FROM LOGIN_FAILS WHERE ipaddress='1.2.3.4' AND added BETWEEN (NOW() - INTERVAL $time_for_ban_try 分钟)现在()”;

如果我理解有误,请告诉我。

关于mysql - 正确执行临时禁令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1416752/

相关文章:

Java内存不足使用PostgreSQL

database - 如何明智地保持更新多个 postgres 数据库、表和函数

django - Celery eventlet 工作线程使用过多的数据库连接

c# - 确定文件中更改的字节的开始和结束范围

PHP:迭代 SQL Return 的最佳方法

php - Laravel:创建动态属性

mysql - PHPStorm Mysql数据源:权限被拒绝:connect

postgresql - Gitlab 500 错误:PG::ConnectionBad

php - 尽管在 Laravel 5 中使用唯一验证,但字段重复

php - 在 2037 年之后存储 MySQL 日期的正确方法