限制失败的登录尝试次数

时间:2011-06-15 12:22:13

标签: php mysql security captcha

我想限制失败的登录尝试。例如,如果特定用户尝试使用错误的用户名或密码登录4次,我应该在第4次显示CAPTCHA而不是在特定时间内阻止,并且除非他提供有效的用户名和密码,否则将继续显示CAPTCHA。用户成功登录后,登录尝试将重置为ZERO。

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

5 个答案:

答案 0 :(得分: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(预备语句)在数据库中插入数据。

答案 1 :(得分:1)

你在保护什么?

随机用户内容,用户名。

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

你在问这个怎么做,或者你应该用哪个?

答案 2 :(得分:1)

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

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

详细说明要实施的安全性:组合

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

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

执行此操作的最佳方法是使用数据库。

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

(a)IP地址(此人试图登录的地方) (b)登录尝试次数 (c)日期/时间(或:当前时间戳)

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

如果此人在网吧中怎么办?或使用公共Wi-Fi?还是热点?或者,一所学校?办公室?等等

如果您屏蔽了IP地址,则会影响所有尝试从该位置登录您网站的人。

如果您的网站涉及银行,军事装置或五角大楼等问题,这不是问题。

但是,如果您的网站是一个企业(买卖,游戏,无论如何),那么阻止特定地址只会让您的客户感到烦恼!