临时禁止

时间:2009-09-13 03:11:02

标签: mysql postgresql

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

LOGIN_FAILS表:

  • id PK,serial / auto_increment
  • ipaddress int / text /您喜欢的任何内容
  • 添加了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();

这可以显示为

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

失败:1,2,3

失败设置为时间范围:

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

现在你可以连续尝试一次:

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

现在你可以连续两次尝试:

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

但正确的方法是将这个时间块保持5分钟

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

现在你可以连续三次尝试

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

但你不想将当前时间用作块(0:00-0:05,0:05-0:10等),因为如果禁令发生在0:04,则下一个禁止检查时间块为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()

3 个答案:

答案 0 :(得分:2)

正如我从你的长期问题中所理解的那样,你需要知道一个ip是否禁止因为它的失败登录尝试在最后$ time_for_ban_try中。然后你可以试试 -

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

$ sql =“SELECT IF(COUNT(id)&lt; 3,'false','true')AS is_banned FROM LOGIN_FAILS WHERE ipaddress ='1.2.3.4'AND并添加了BETWEEN(NOW() - INTERVAL $ time_for_ban_try MINUTE )和现在()“;

如果我错了,请告诉我。

答案 1 :(得分:1)

你的问题很长,我承认我正在努力解开你所问的问题。我相信你在问:如果我检查“过去X分钟有多少次失败?”然后锁定将持续到最近的最小故障发生;我如何确保它总是持续5分钟?

如果这就是您所要求的,那么这是一个相当简单的方法:在每次登录失败时,询问数据库“过去X分钟内有多少次失败?”。如果这些加上刚刚失败的那个是3或更多,那么在用户的数据库行上设置一个列 - 比如locked_until - 到现在+ 5分钟。

现在,修改您的登录代码,首先检查帐户是否被锁定。

答案 2 :(得分:1)

Memcache非常适合这种事情,并且会比数据库表给系统带来更少的开销(和更少的代码)。您可以通过设置IP-&gt; #_ of_failures的key-&gt;值对来计算登录失败,并将其缓存为您想要跟踪登录失败的秒数。如果值(失败次数)太高,则为该IP缓存一个唯一的“禁止”值,持续5分钟。

请注意禁止用户登录失败的事实非常令人烦恼,如果这样做,您应该将允许的失败次数设置为非常高。用户通常拥有一组密码(按照“重要性”的顺序),如果他们忘记密码,他们将尝试在您的网站上使用这些密码。

还要注意多个人可能使用相同的IP(如在大学校园或私人网络中)。