限制登录尝试失败的次数

Rom*_*man 5 php mysql security captcha

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

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

Mat*_*tis 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
Run Code Online (Sandbox Code Playgroud)

这样的事情.

编辑:

这是非常古老的代码,我现在看到了一些问题.但是,至少应该使用PDO(预准备语句)在数据库中插入数据.

  • 记得在成功登录后重置`Failed_logins`. (2认同)