如何在MySQL中添加登录尝试功能并通过PHP代码实现
MySQL登录尝试功能的PHP实现方案
你已经通过ALTER TABLE users ADD COLUMN login_attempts INT DEFAULT 0;完成了字段添加,下面是对应的PHP代码实现,包含登录失败计数、成功重置次数,以及可选的账户锁定逻辑。
1. 数据库连接(PDO实现,推荐)
使用PDO可避免SQL注入,提升代码安全性:
<?php // 数据库配置信息 $dbHost = 'localhost'; $dbName = '你的数据库名'; $dbUser = '你的数据库用户名'; $dbPass = '你的数据库密码'; try { $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { die("数据库连接失败: " . $e->getMessage()); } ?>
2. 核心登录验证逻辑
2.1 基础版:失败计数+成功重置
<?php // 从登录表单获取用户输入 $username = trim($_POST['username'] ?? ''); $password = trim($_POST['password'] ?? ''); // 查询用户信息及当前登录尝试次数 $stmt = $pdo->prepare("SELECT id, password, login_attempts FROM users WHERE username = ?"); $stmt->execute([$username]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user) { // 验证密码(假设密码通过password_hash加密存储) if (!password_verify($password, $user['password'])) { // 密码错误,尝试次数+1 $updateStmt = $pdo->prepare("UPDATE users SET login_attempts = login_attempts + 1 WHERE id = ?"); $updateStmt->execute([$user['id']]); $remainingAttempts = 3 - ($user['login_attempts'] + 1); echo "用户名或密码错误,剩余尝试次数: " . $remainingAttempts; exit; } else { // 登录成功,重置尝试次数为0 $resetStmt = $pdo->prepare("UPDATE users SET login_attempts = 0 WHERE id = ?"); $resetStmt->execute([$user['id']]); // 登录成功后的逻辑:比如设置会话 session_start(); $_SESSION['user_id'] = $user['id']; echo "登录成功!"; // 跳转到后台页面 // header("Location: dashboard.php"); // exit; } } else { echo "用户名不存在"; } ?>
2.2 进阶版:添加账户锁定功能
如果需要限制多次失败后的登录,可加入锁定逻辑(比如连续3次失败后锁定15分钟):
首先添加记录最后失败时间的字段:
ALTER TABLE users ADD COLUMN last_login_attempt DATETIME NULL;
然后修改登录验证代码:
<?php session_start(); $username = trim($_POST['username'] ?? ''); $password = trim($_POST['password'] ?? ''); $stmt = $pdo->prepare("SELECT id, password, login_attempts, last_login_attempt FROM users WHERE username = ?"); $stmt->execute([$username]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user) { $lockThreshold = 3; // 允许的最大失败次数 $lockMinutes = 15; // 锁定时长(分钟) $currentTime = new DateTime(); // 检查是否处于锁定状态 if ($user['login_attempts'] >= $lockThreshold) { $lastAttemptTime = new DateTime($user['last_login_attempt']); $interval = $currentTime->diff($lastAttemptTime); $minutesPassed = $interval->i + ($interval->h * 60); if ($minutesPassed < $lockMinutes) { echo "账户已锁定,请" . ($lockMinutes - $minutesPassed) . "分钟后再试"; exit; } else { // 超过锁定时长,重置尝试次数 $resetStmt = $pdo->prepare("UPDATE users SET login_attempts = 0 WHERE id = ?"); $resetStmt->execute([$user['id']]); // 重新查询用户信息 $stmt->execute([$username]); $user = $stmt->fetch(PDO::FETCH_ASSOC); } } // 验证密码 if (!password_verify($password, $user['password'])) { // 更新尝试次数和最后失败时间 $updateStmt = $pdo->prepare("UPDATE users SET login_attempts = login_attempts + 1, last_login_attempt = NOW() WHERE id = ?"); $updateStmt->execute([$user['id']]); $remainingAttempts = $lockThreshold - ($user['login_attempts'] + 1); echo "用户名或密码错误,剩余尝试次数: " . $remainingAttempts; exit; } else { // 登录成功,重置尝试次数 $resetStmt = $pdo->prepare("UPDATE users SET login_attempts = 0, last_login_attempt = NULL WHERE id = ?"); $resetStmt->execute([$user['id']]); $_SESSION['user_id'] = $user['id']; echo "登录成功!"; // header("Location: dashboard.php"); // exit; } } else { echo "用户名不存在"; } ?>
3. 密码加密说明
如果你的用户密码尚未加密,注册时请使用password_hash存储安全的哈希值:
<?php // 注册流程示例 $username = trim($_POST['reg_username'] ?? ''); $rawPassword = trim($_POST['reg_password'] ?? ''); $hashedPassword = password_hash($rawPassword, PASSWORD_DEFAULT); $stmt = $pdo->prepare("INSERT INTO users (username, password, login_attempts) VALUES (?, ?, 0)"); $stmt->execute([$username, $hashedPassword]); echo "注册成功!"; ?>
内容的提问来源于stack exchange,提问作者SHARIFF100
相关产品推荐
相关产品推荐

