2011-06-15 133 views
5

我想限制失败的登录尝试次数。例如,如果某个特定用户尝试使用错误的用户名或密码登录4次,我应该在第4次显示CAPTCHA而不是屏蔽某些特定时间,并且除非他提供有效的用户名和密码,否则不断显示CAPTCHA。一旦用户成功登录,登录尝试将被重置为零。限制失败的登录尝试次数

是否从安全的角度来检查用户名而不是IP地址?这种方法是否可以在不使用数据库的情况下实施?因为我认为我不需要存储时间,因为我只会显示recaptcha? 请给出你的意见。

+1

http://stackoverflow.com/questions/580534/best-way-to-limit-and-record-login-attempts http://stackoverflow.com/questions/679756/limiting-user-login-attempts- in-php – Jacob 2011-06-15 12:23:54

回答

8

你不想使用数据库'失败的登录数' - 检查?然后只需使用一个cookie并检查它。当然,他们可以将其删除,但这很麻烦。

但是,我怀疑你已经从数据库中获取用户名和密码,为什么不在你登录时获取失败登录的最后一个号码呢?

if (isset($_POST['submit_login'])) { 

    if (isset($_POST['username']) && isset($_POST['password'])) { 
     $username = mysql_real_escape_string($_POST['username']); 
     $password = mysql_real_escape_string($_POST['password']); 
     // id = unique primary key 
     $rs = mysql_query('SELECT id,Username,Password,Failed_logins,IP_address FROM Users WHERE Username = '.$username.''); 
     $num = mysql_num_rows($rs); 
     if ($num > 0) { 
      // I would add a password hash here to $password, and check against the hashed Password from the database 
      // But let's check the clean passwords 
      $row = mysql_fetch_array($rs); 
      if ($password == $row['Password']) { 
       // Successful login, set session or whatever you need 
       // Reset failed logins 
       mysql_query('UPDATE Users SET Failed_logins = 0 WHERE id = '.$row['id'].''); 
       header('location: success.php'); 
      } else { 
       // Failed password check 
       if ($row['Failed_logins'] > 3) { 
        // Redirect to captcha 
        header('location: captcha.php'); 
       } else { 
        $ip = $_SERVER['REMOTE_ADDR']; 
        if ($row['IP_address'] != $ip) { 
         // New ip adress, reset failed logins 
         $failed_logins = 0; 
        } else { 
         // Increment failed logins 
         $failed_logins = $row['Failed_logins']+1; 
        } 
        mysql_query('UPDATE Users SET Failed_logins = '.$failed_logins.',IP_address = '.$ip.' WHERE id = '.$row['id'].' '); 
       } // End check Failed_logins > 3 
      } 
     } else { 
      // No such Username found in database 
      $error = 'no_such_username'; 
     } // End username check from database 

    } else { 
     // Either username or password is missing 
     $error = 'incomplete_form'; 
    } // end check for username and password 

} // end main submit_login check 

就是这样的。

编辑:

这是真的老代码,我现在看到的一些问题吧。但是,至少您应该始终使用PDO(准备好的语句)在数据库中插入数据。

+2

记得在成功登录后重置'Failed_logins'。 – jensgram 2011-06-15 12:33:22

+0

是的,这很好。所以只有成功登录后才能重置failed_login?所以即使一个人在一年后尝试,也不会允许?我应该添加另一列像login_time并比较时间?可以说一个人只能在24小时内尝试3次?这是个好主意吗? – Roman 2011-06-15 12:40:31

+0

如果攻击者持续提供不存在的用户名,该怎么办? – Roman 2011-06-15 12:45:03

0

您应该将尝试保存在数据库中并检查用户。

1

你在保护什么?

随机的用户专用内容,用户名。

银行信息(我怀疑..)或其他敏感数据,IP可能没问题,只要你使用范围。

你在问怎么做,或者你应该用什么?

1

您确实需要时间,您会如何确定登录尝试是否已过期?如果我在10年的时间内无法登录4次,我会被阻止。您想阻止那些在短时间内尝试多次登录尝试的人。

我建议您使用数据库 - 因为您将同时保存登录的详细历史记录。但是像memcached这样基于内存的解决方案也足够了。

详细说明要实现哪种安全性:组合

结合使用的用户名和IP地址,并将它们存储到您的数据库中。

  1. 使用用户名登录尝试直接保护您的用户免受企图。
  2. 使用ip地址信息仅观察检测,并在需要时采取措施。
+0

感谢您的想法。现在,存储用户的用户名或IP地址会更有帮助吗?如果攻击者继续提供不存在的用户名和密码,会发生什么情况? – Roman 2011-06-15 12:42:55

0

这样做的最好方法是使用数据库。

您需要在数据库中创建一个单独的表,这将存储三个变量:

(一)IP地址(如该人试图登录) (B)的登录尝试 数( C)日期/时间(或:当前时间戳)

这种方法唯一的问题是与第一个变量:IP地址

如果该人是在网吧呢?或者使用公共无线网络?还是热点?或者,一所学校?办公室? etc等

如果您阻止了IP地址,它会影响每个尝试从该位置登录您的网站的人。

如果您的网站涉及银行,军事装置或五角大楼等问题,这不是问题。但是,如果你的网站是一个商业(购买和销售,游戏,无论),然后阻止一个特定的地址只会激怒你的客户!