You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHP中限制用户登录尝试次数并实现3分钟封禁

PHP登录尝试限制与3分钟临时封禁实现方案

我来帮你解决这个登录限制的问题,核心思路是用Session存储失败次数和封禁截止时间,结合时间判断来实现自动封禁与解封。下面是调整后的完整代码,我会一步步拆解关键逻辑:

<?php
session_start(); // 必须先启动Session,才能存储登录状态

class User {
    // 用户登录方法
    public function logIn($user, $password) {
        // 第一步:先检查用户是否处于封禁期
        if (isset($_SESSION['ban_until']) && time() < $_SESSION['ban_until']) {
            $remainingTime = ceil(($_SESSION['ban_until'] - time()) / 60);
            return "You have been banned. Please try again in {$remainingTime} minute(s).";
        }

        // 初始化登录失败次数(如果Session里还没存的话)
        if (!isset($_SESSION['login_attempts'])) {
            $_SESSION['login_attempts'] = 0;
        }

        // 数据库连接(这里替换成你的数据库信息)
        $con = new mysqli("localhost", "root", "", "animal");
        if ($con->connect_error) {
            die("Connection failed: " . $con->connect_error);
        }

        // 重点:用预处理语句防止SQL注入,别直接拼接用户输入!
        $sql = "SELECT * FROM users WHERE username = ? AND password = ?";
        $stmt = $con->prepare($sql);
        $stmt->bind_param("ss", $user, $password);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows === 1) {
            // 登录成功:重置失败次数和封禁状态
            $_SESSION['login_attempts'] = 0;
            unset($_SESSION['ban_until']);
            return "Login successful!";
        } else {
            // 登录失败:累加失败次数
            $_SESSION['login_attempts']++;

            // 检查是否达到3次失败阈值
            if ($_SESSION['login_attempts'] >= 3) {
                // 设置封禁截止时间:当前时间 + 3分钟(180秒)
                $_SESSION['ban_until'] = time() + 180;
                $_SESSION['login_attempts'] = 0; // 重置次数,避免重复触发封禁提示
                return "You have had too many tries. Please try again after 3 minutes.";
            } else {
                $remainingAttempts = 3 - $_SESSION['login_attempts'];
                return "Invalid username or password. You have {$remainingAttempts} attempt(s) left.";
            }
        }

        $stmt->close();
        $con->close();
    }
}

// 示例调用(假设前端是POST提交用户名密码)
$userObj = new User();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'] ?? '';
    $password = $_POST['password'] ?? '';
    $loginMsg = $userObj->logIn($username, $password);
    echo $loginMsg;
}
?>

核心逻辑拆解:

  1. Session状态管理:通过session_start()开启Session,用$_SESSION['login_attempts']存储失败次数,$_SESSION['ban_until']存储封禁截止时间戳。
  2. 封禁前置检查:每次登录请求先判断用户是否在封禁期内,如果是直接返回剩余封禁时间提示。
  3. 失败次数累加与触发封禁:登录失败时递增次数,达到3次就设置封禁截止时间(当前时间+180秒),同时重置失败次数避免重复触发。
  4. 自动解封:当系统时间超过ban_until的时间戳时,封禁状态自动失效,用户可以重新尝试登录。
  5. 登录成功重置状态:一旦登录成功,立即清空失败次数和封禁标记,恢复正常登录权限。

额外安全提示:

  • 原代码直接把用户输入拼进SQL语句,存在严重SQL注入风险,我改用了mysqli预处理语句,一定要坚持这种写法!
  • 数据库里别存明文密码,建议用password_hash()加密后存储,登录时用password_verify()验证。

内容的提问来源于stack exchange,提问作者user8718169

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:39:44