Node.js中从PostgreSQL获取数据实现用户登录验证的问题
问题分析与解决方案
你的代码核心问题
混用
async/await和.then()导致逻辑混乱
你已经用await获取了client.query的返回结果,完全没必要再链式调用.then()。当前代码里的.then()回调不仅多余,还会造成变量作用域混乱——回调里的arr和外层定义的arr是同一个,但此时arr已经是查询结果的rows数组,逻辑完全拧巴。未正确提取查询结果中的用户数据
data.rows返回的是匹配条件的用户数组(正常来说邮箱应该是唯一的,所以数组长度要么是0要么是1),要拿到具体的字段值,得取数组的第一个元素,比如arr[0].email、arr[0].password。
查询返回空数组的可能原因
- 传入的
req.body.email在数据库中不存在; - 表名/字段名拼写错误:PostgreSQL对标识符(表名、字段名)大小写敏感,如果创建表时没加双引号,实际会被转成小写,比如你写的
user_table如果实际是UserTable,查询就会失败; - 前端传参错误:可以加
console.log(email)确认req.body.email是否拿到了正确的值。
修正后的完整登录验证代码
router.post("/login", async (req, res, next) => { try { const { email, password } = req.body; // 先校验前端传参是否完整 if (!email || !password) { return res.status(400).json({ message: "邮箱和密码不能为空" }); } // 查询匹配邮箱的用户 const data = await client.query(`SELECT * FROM user_table WHERE email = $1;`, [email]); const users = data.rows; // 判断是否找到用户 if (!users || users.length === 0) { return res.status(401).json({ message: "登录认证失败!邮箱未注册" }); } // 取出唯一匹配的用户(因邮箱唯一) const user = users[0]; // 重要提醒:密码必须哈希存储,绝对不能直接对比明文! // 假设用bcrypt哈希密码,验证代码示例: // const isPasswordMatch = await bcrypt.compare(password, user.password); // if (!isPasswordMatch) { // return res.status(401).json({ message: "登录认证失败!密码错误" }); // } // 验证通过后的后续操作(比如生成token) res.status(200).json({ message: "登录成功", userInfo: { email: user.email, fullName: user.fullName, isSuperuser: user.isSuperuser } }); } catch (error) { // 捕获数据库查询或其他异常 console.error("登录出错:", error); res.status(500).json({ message: "服务器内部错误" }); next(error); } });
关键注意事项
- 密码安全:数据库绝对不能存明文密码,必须用bcrypt、Argon2等哈希算法加密后存储,验证时用对应方法对比哈希值;
- 邮箱唯一性:建议给
user_table的email字段添加唯一约束,避免同一邮箱重复注册; - 错误捕获:一定要用
try/catch包裹异步操作,防止未处理的异常导致服务器崩溃。
内容的提问来源于stack exchange,提问作者nabsabt
相关产品推荐
相关产品推荐

