【2025年8月最新消息】近期网络安全事件频发,某知名社交平台因登录系统漏洞导致数百万用户数据泄露,这再次提醒我们,一个安全可靠的用户认证系统对任何网站都至关重要,今天我就来手把手教你如何用PHP和MySQL实现既安全又高效的登录系统。
首先我们需要设计用户数据表,打开你的MySQL管理工具(比如phpMyAdmin),创建一个名为users
的表:
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `email` varchar(100) NOT NULL, `password_hash` varchar(255) NOT NULL, `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `last_login` datetime DEFAULT NULL, `is_active` tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
这个表结构包含了用户登录所需的基本信息,注意我们存储的是密码哈希值而不是明文密码,这是安全的第一道防线。
创建一个config.php
文件存放数据库连接信息:
<?php $host = 'localhost'; $dbname = 'your_database_name'; $username = 'your_db_username'; $password = 'your_db_password'; try { $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $username, $password); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { die("数据库连接失败: " . $e->getMessage()); } ?>
创建register.php
处理用户注册:
<?php require 'config.php'; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = trim($_POST['username']); $email = trim($_POST['email']); $password = $_POST['password']; $confirm_password = $_POST['confirm_password']; // 简单验证 if (empty($username) || empty($email) || empty($password)) { $error = "所有字段都必须填写"; } elseif ($password !== $confirm_password) { $error = "两次输入的密码不一致"; } elseif (strlen($password) < 8) { $error = "密码长度至少需要8个字符"; } else { // 检查用户名和邮箱是否已存在 $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? OR email = ?"); $stmt->execute([$username, $email]); if ($stmt->rowCount() > 0) { $error = "用户名或邮箱已被注册"; } else { // 密码哈希处理 $password_hash = password_hash($password, PASSWORD_DEFAULT); // 插入新用户 $stmt = $pdo->prepare("INSERT INTO users (username, email, password_hash) VALUES (?, ?, ?)"); if ($stmt->execute([$username, $email, $password_hash])) { $success = "注册成功!请登录"; header("Refresh: 2; url=login.php"); } else { $error = "注册失败,请稍后再试"; } } } } ?> <!DOCTYPE html> <html> <head>用户注册</title> </head> <body> <h2>用户注册</h2> <?php if (isset($error)) echo "<p style='color:red'>$error</p>"; ?> <?php if (isset($success)) echo "<p style='color:green'>$success</p>"; ?> <form method="post"> <div> <label>用户名:</label> <input type="text" name="username" required> </div> <div> <label>电子邮箱:</label> <input type="email" name="email" required> </div> <div> <label>密码:</label> <input type="password" name="password" required> </div> <div> <label>确认密码:</label> <input type="password" name="confirm_password" required> </div> <button type="submit">注册</button> </form> <p>已有账号?<a href="login.php">立即登录</a></p> </body> </html>
创建login.php
处理用户登录:
<?php session_start(); require 'config.php'; if (isset($_SESSION['user_id'])) { header("Location: dashboard.php"); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $username = trim($_POST['username']); $password = $_POST['password']; // 查找用户 $stmt = $pdo->prepare("SELECT id, username, password_hash FROM users WHERE username = ? AND is_active = 1"); $stmt->execute([$username]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user && password_verify($password, $user['password_hash'])) { // 登录成功,设置会话 $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; // 更新最后登录时间 $pdo->prepare("UPDATE users SET last_login = NOW() WHERE id = ?")->execute([$user['id']]); // 重定向到受保护页面 header("Location: dashboard.php"); exit; } else { $error = "用户名或密码错误"; } } ?> <!DOCTYPE html> <html> <head>用户登录</title> </head> <body> <h2>用户登录</h2> <?php if (isset($error)) echo "<p style='color:red'>$error</p>"; ?> <form method="post"> <div> <label>用户名:</label> <input type="text" name="username" required> </div> <div> <label>密码:</label> <input type="password" name="password" required> </div> <button type="submit">登录</button> </form> <p>还没有账号?<a href="register.php">立即注册</a></p> </body> </html>
// 在login.php中添加 $stmt = $pdo->prepare("SELECT COUNT(*) FROM login_attempts WHERE ip_address = ? AND attempt_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)"); $stmt->execute([$_SERVER['REMOTE_ADDR']]); $attempts = $stmt->fetchColumn(); if ($attempts > 5) { $error = "登录尝试次数过多,请1小时后再试"; // 可以记录日志或发送警报 }
// 在登录表单前生成令牌 if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } // 在表单中添加 <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> // 提交时验证 if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { die("CSRF验证失败"); }
// 生成重置令牌 $reset_token = bin2hex(random_bytes(32)); $expires_at = date('Y-m-d H:i:s', strtotime('+1 hour')); $stmt = $pdo->prepare("UPDATE users SET reset_token = ?, reset_expires = ? WHERE email = ?"); $stmt->execute([$reset_token, $expires_at, $email]); // 发送包含重置链接的邮件(实际应用中实现) $reset_link = "https://yoursite.com/reset_password.php?token=$reset_token";
Q:为什么要用password_hash()而不是md5()? A:md5()早已不安全,password_hash()使用bcrypt等现代算法,自动加盐,更安全。
Q:如何实现"记住我"功能? A:可以使用长期有效的安全令牌存储在cookie中,与数据库中的记录匹配验证。
Q:我的网站很小,也需要这么复杂吗? A:安全无小事,即使小型网站也会成为攻击目标,基础安全措施是必须的。
通过PHP和MySQL实现用户登录系统并不复杂,但安全性至关重要,本文介绍的方法涵盖了现代Web应用登录系统的最佳实践,包括密码安全、会话管理、CSRF防护等关键方面,根据你的具体需求,还可以添加更多功能如双因素认证、登录日志等。
安全是一个持续的过程,不是一次性任务,定期更新你的代码,关注最新的安全威胁,才能确保用户数据始终安全。
本文由 风慧艳 于2025-08-02发表在【云服务器提供商】,文中图片由(风慧艳)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/512790.html
发表评论