如何在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; } ?>
核心逻辑拆解:
- Session状态管理:通过
session_start()开启Session,用$_SESSION['login_attempts']存储失败次数,$_SESSION['ban_until']存储封禁截止时间戳。 - 封禁前置检查:每次登录请求先判断用户是否在封禁期内,如果是直接返回剩余封禁时间提示。
- 失败次数累加与触发封禁:登录失败时递增次数,达到3次就设置封禁截止时间(当前时间+180秒),同时重置失败次数避免重复触发。
- 自动解封:当系统时间超过
ban_until的时间戳时,封禁状态自动失效,用户可以重新尝试登录。 - 登录成功重置状态:一旦登录成功,立即清空失败次数和封禁标记,恢复正常登录权限。
额外安全提示:
- 原代码直接把用户输入拼进SQL语句,存在严重SQL注入风险,我改用了mysqli预处理语句,一定要坚持这种写法!
- 数据库里别存明文密码,建议用
password_hash()加密后存储,登录时用password_verify()验证。
内容的提问来源于stack exchange,提问作者user8718169
相关产品推荐
相关产品推荐

