Php 限制失败的登录尝试数

Php 限制失败的登录尝试数,php,mysql,security,captcha,Php,Mysql,Security,Captcha,我想限制失败的登录尝试。例如,如果某个特定用户尝试使用错误的用户名或密码登录4次,我应该在第4次显示验证码,而不是在某个特定时间阻塞,并继续显示验证码,除非他提供了有效的用户名和密码。用户成功登录后,登录尝试将重置为零 从安全角度来看,检查用户名而不是IP地址的想法是否可行?这种方法可以在不使用数据库的情况下实现吗?因为我认为我不需要存储时间,因为我将只显示recaptcha? 请给出您的意见。您应该将尝试保存在数据库中并检查用户。您在保护什么 随机用户内容,用户名 银行信息(我怀疑…)或其他敏

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

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

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

您在保护什么

随机用户内容,用户名

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


您是在问如何做,还是应该使用哪个?

您确实需要时间,否则您将如何确定登录尝试是否已过期?如果我在10年内登录4次失败,我将被阻止。您希望阻止那些在短时间内尝试多次登录的用户

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

要详细说明要实现的安全性:一个组合

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

  • 使用用户名上的登录尝试直接保护用户不受尝试的影响
  • 使用ip地址信息仅观察检测,并在需要时采取措施

  • 您不想将数据库用于“失败登录数”-检查?然后用饼干检查一下。当然,他们可以移除它,但这很麻烦

    然而,我怀疑您已经从数据库中获取了用户名和密码,为什么不同时获取上次登录失败的次数呢

    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(准备好的语句)在数据库中插入数据。

    最好的方法是使用数据库

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

    (a) IP地址(用户尝试登录的位置) (b) 登录尝试次数 (c) 日期/时间(或:当前时间戳)

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

    如果此人在网吧里怎么办?还是使用公共Wi-fi?还是热点?还是学校?办公室?等等等等

    如果您阻止IP地址,则会影响试图从该位置登录您网站的所有人

    如果你的网站涉及银行、军事设施或五角大楼之类的东西,这不是问题


    但是,如果你的网站是一个企业(买卖、游戏等等),那么封锁一个特定的地址只会激怒你的客户

    记住在成功登录后重置失败的登录。是的,这很好。那么,只有在成功登录后,才能重置失败的_登录?所以即使一个人在一年后尝试,它也不允许?我是否应该添加另一列,如login_time并比较时间?假设一个人只能在24小时内尝试3次?这是个好主意吗?如果攻击者继续提供不存在的用户名怎么办?我不是想写完整的代码,只是给你一个框架。当然,当失败的\u登录成功时,您应该将其归零。如果您愿意,可以实施超时。你是对的,你不应该让一个用户增加另一个用户的失败登录。我将存储用户的IP地址,如果IP地址发生变化,则将失败的\u登录归零。我会再写一些代码。谢谢你的主意。现在,存储用户的用户名或IP地址是否更有帮助?如果攻击者继续提供不存在的用户名和密码,会发生什么情况?