如何在PHP中验证用户名密码?代码导致APP崩溃求助
解决PHP登录验证时的崩溃问题及安全优化建议
嘿,我来帮你搞定这个问题!你的代码现在有几个关键问题导致崩溃和功能异常,咱们一步步来梳理修复:
核心问题分析
- 未处理SQL查询失败场景:当用户输入的邮箱包含特殊字符(比如单引号),或是数据库连接出问题时,
mysqli_query会返回false,此时直接调用mysqli_num_rows(false)会触发致命错误,这就是你遇到“输错密码时程序崩溃”的根本原因。 - 重复输出非法JSON:登录成功时你连续
echo了两个JSON字符串,这会让输出内容格式完全混乱,前端根本无法解析。 - 严重SQL注入风险:直接把用户输入的邮箱、密码拼进SQL语句里,攻击者很容易构造特殊输入窃取或篡改数据库数据。
- 密码明文存储:直接将密码明文存在数据库是严重的安全漏洞,一旦数据库泄露,所有用户密码都会直接暴露。
修复并优化后的代码
下面是调整后的完整代码,我加了详细注释帮你理解:
<?php include 'DBConfig.php'; // 初始化并检查数据库连接 $con = mysqli_connect($HostName, $HostUser, $HostPass, $DatabaseName); if (!$con) { die(json_encode(['status' => 'error', 'message' => '数据库连接失败: ' . mysqli_connect_error()])); } // 获取并验证输入数据 $json = file_get_contents('php://input'); $obj = json_decode($json, true); // 检查必填字段是否存在 if (!isset($obj['email'], $obj['password'])) { echo json_encode(['status' => 'error', 'message' => '请提供完整的邮箱和密码']); mysqli_close($con); exit; } $email = $obj['email']; $password = $obj['password']; // 使用预处理语句彻底防止SQL注入 $stmt = mysqli_prepare($con, "SELECT name, email, password FROM UserRegistrationTable WHERE email = ?"); mysqli_stmt_bind_param($stmt, "s", $email); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); // 处理查询结果 if ($result) { if (mysqli_num_rows($result) > 0) { $user = mysqli_fetch_assoc($result); // 验证密码(注意:数据库中必须存储password_hash生成的哈希值) if (password_verify($password, $user['password'])) { // 登录成功,返回用户信息(绝不返回密码) echo json_encode([ 'status' => 'success', 'message' => '登录成功', 'details' => [ 'name' => $user['name'], 'email' => $user['email'] ] ]); } else { // 密码不匹配 echo json_encode(['status' => 'error', 'message' => '无效的用户名或密码,请重试']); } } else { // 未找到对应用户 echo json_encode(['status' => 'error', 'message' => '无效的用户名或密码,请重试']); } } else { // 查询执行出错 echo json_encode(['status' => 'error', 'message' => '查询失败: ' . mysqli_error($con)]); } // 清理资源并关闭连接 mysqli_stmt_close($stmt); mysqli_close($con); ?>
关键优化说明
- 完善错误处理:增加了数据库连接检查、输入合法性校验,以及SQL查询失败的捕获,避免意外情况导致程序崩溃。
- 杜绝SQL注入:用预处理语句+参数绑定的方式,彻底阻断SQL注入攻击的可能。
- 密码安全升级:使用
password_verify验证密码,前提是用户注册时必须用password_hash($password, PASSWORD_DEFAULT)生成哈希值存入数据库(如果现在是明文存储,建议尽快批量更新为哈希值)。 - 规范JSON输出:统一输出单个合法JSON对象,包含状态、消息和用户信息,前端可以轻松解析。
- 敏感信息保护:登录成功后不再返回密码,避免敏感数据泄露。
内容的提问来源于stack exchange,提问作者Abhishek DS
相关产品推荐
相关产品推荐

