php实现忘记密码
PHP 实现忘记密码功能
忘记密码功能通常包括以下步骤:用户请求重置密码、系统发送重置链接、用户通过链接设置新密码。以下是具体实现方法:
数据库准备
创建用户表时需包含email、password(加密存储)、reset_token和reset_expires字段。后两个字段用于存储重置令牌和过期时间。
ALTER TABLE users ADD COLUMN reset_token VARCHAR(255) DEFAULT NULL;
ALTER TABLE users ADD COLUMN reset_expires DATETIME DEFAULT NULL;
生成重置令牌
当用户请求重置密码时,生成唯一令牌并设置有效期(通常1-2小时):
$token = bin2hex(random_bytes(32));
$expires = date('Y-m-d H:i:s', time() + 3600); // 1小时后过期
// 存储到数据库
$stmt = $pdo->prepare("UPDATE users SET reset_token=?, reset_expires=? WHERE email=?");
$stmt->execute([$token, $expires, $email]);
发送重置邮件
使用PHP邮件函数或库(如PHPMailer)发送包含重置链接的邮件:
$resetLink = "https://example.com/reset-password?token=$token";
$subject = "Password Reset Request";
$message = "Click the link to reset your password: $resetLink";
mail($email, $subject, $message);
验证重置令牌
用户点击链接后验证令牌是否有效且未过期:
$stmt = $pdo->prepare("SELECT * FROM users WHERE reset_token=? AND reset_expires > NOW()");
$stmt->execute([$_GET['token']]);
$user = $stmt->fetch();
if (!$user) {
die("Invalid or expired token");
}
更新密码
验证通过后允许设置新密码,并清除重置令牌:
$newPassword = password_hash($_POST['new_password'], PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET password=?, reset_token=NULL, reset_expires=NULL WHERE reset_token=?");
$stmt->execute([$newPassword, $_POST['token']]);
安全注意事项
- 使用HTTPS确保传输安全
- 限制密码重置请求频率防止滥用
- 令牌使用后立即失效
- 新密码需满足复杂度要求
- 记录密码重置操作日志
完整流程示例
- 用户访问忘记密码页面提交邮箱
- 系统生成令牌并发送邮件
- 用户点击邮件中的链接
- 系统验证令牌并显示密码重置表单
- 用户提交新密码
- 系统更新密码并提示成功
实现时可结合前端验证和CSRF防护增强安全性。对于生产环境,建议使用成熟的认证库如Laravel的Auth系统或Symfony的Security组件。







