php代码示例如何实现登录验证_php登录验证代码示例【示例】

17次阅读

PHP 登录验证必须用 password_hash()和 password_verify()处理密码哈希,禁用明文比对与 MD5/SHA1;须用 PDO 预处理防注入;登录后调用 session_regenerate_id(true)并设安全 Cookie 参数;需过滤输入、防爆破、时序攻击;忘记密码流程须严格校验 token。

php 代码示例如何实现登录验证_php 登录验证代码示例【示例】

PHP 登录验证必须校验密码哈希,不能明文比对

直接用 $_POST['password'] === $stored_password 是严重安全漏洞。PHP 自带的 password_hash()password_verify() 是唯一推荐方式。数据库里存的必须是哈希值(如 $2y$10$……),不是明文或简单 MD5。

常见错误:用 md5()sha1() 存密码,或在 SQL 查询里拼接用户输入导致注入。

  • 注册时用 password_hash($_POST['password'], PASSWORD_ARGON2ID)(优先 Argon2,若不支持则用 PASSWORD_DEFAULT
  • 登录时查出用户记录后,用 password_verify($_POST['password'], $row['password_hash']) 判断,而不是在 SQL 里比对
  • 查询语句必须用 PDO 预处理,例如:$stmt = $pdo->prepare("SELECT id, password_hash FROM users WHERE username = ?")

登录成功后必须重置会话并设置安全 Cookie

仅靠 session_start() 不够。PHP 默认会话容易被劫持或固定,尤其在 HTTP 环境下。

  • 登录验证通过后立即调用 session_regenerate_id(true),销毁旧 session ID
  • 设置 session_set_cookie_params(['secure' => true, 'httponly' => true, 'samesite' => 'Strict'])(HTTPS 环境下 secure 必须为 true
  • 写入登录态到 $_SESSION['user_id'] 即可,不要存密码、token 或敏感字段
  • 避免在 URL 中暴露 session ID,禁用 session.use_trans_sid

空用户名、SQL 注入、爆破攻击这三类请求要主动拦截

登录接口是攻击高频入口,光靠 前端 限制毫无意义。服务端必须做基础防护。

立即学习PHP 免费学习笔记(深入)”;

  • $_POST['username'] 做长度和字符过滤:trim() + preg_match('/^[a-zA-Z0-9_]{3,20}$/', $user),拒绝空、超长或含特殊字符的输入
  • 失败 5 次后,对同一 IP 或用户名启用 15 分钟临时锁定(可用 Redis 记录:SET login_fail:192.168.1.100 1 EX 900
  • hash_equals() 对比用户名(防时序攻击),虽然实际影响有限,但符合安全实践:hash_equals($expected_user, $input_user)

忘记密码流程不能绕过登录验证直接重置

“忘记密码”页面提交 邮箱 后,生成一次性 token 并发邮件,点击链接跳转到重置页 —— 这个重置页本身仍需服务端校验 token 有效性与时效性,且必须要求用户再次输入新密码两次。

  • token 必须用 random_bytes(32) 生成,存储进数据库时用 hash_hmac('sha256', $token, $_ENV['APP_KEY']) 保存,防止 DB 泄露直接滥用
  • 重置接口(如 /reset-password)必须验证:$token 是否存在、未使用、未过期(建议 1 小时)、对应邮箱是否合法
  • 重置成功后立即清空该 token,并让所有该用户的现有 session 失效(更新数据库 users.last_password_reset 时间戳,登录中间件检查此字段)

实际部署时,password_verify() 的性能开销可忽略,但 Argon2 参数调优(如 memory_cost=65536)会影响服务器并发能力;别为了“看起来快”而降级哈希强度。

text=ZqhQzanResources