Node.js+Express中使用bcrypt对比数据库哈希密码时应用崩溃问题
问题分析与修复方案
你的代码里有两个核心错误导致服务器崩溃,具体修正如下:
错误点1:bcrypt.compare的参数传递错误
你把res.json(data)传给了bcrypt.compare的第二个参数,这会直接向客户端发送查询结果的响应,而且res.json()的返回值是undefined,bcrypt拿到undefined必然报错。正确的做法是从查询结果data里提取出哈希密码,也就是data[0].password。
错误点2:异步回调中直接抛出异常
在bcrypt的回调里throw err会导致Node.js进程崩溃,因为Express无法捕获异步回调里的未处理异常。应该用res.json()把错误信息返回给客户端,而不是直接抛出错误。
修正后的完整代码
const express = require("express"); const mysql = require("mysql"); const cors = require("cors"); const bcrypt = require('bcryptjs') const app = express(); app.use(express.json()) app.use(cors()); const db = mysql.createConnection({ host: "localhost", user: "useraccount", password: "useraccount", database: "users", }); app.post('/login', (req, res) => { const sql = 'SELECT password FROM auth_table WHERE email = ?' db.query(sql, req.body.email, (err, data) => { if (err) return res.json("数据库查询错误"); if (data.length > 0) { // 提取数据库中存储的哈希密码 const hashedPassword = data[0].password; bcrypt.compare(req.body.password, hashedPassword, function (err, result) { if (err) { // 返回错误信息而非抛出异常 return res.json("密码验证失败"); } if (result) { return res.json("登录成功"); } else { // 处理密码不匹配的情况 return res.json("登录失败:密码错误"); } }) } else { return res.json("登录失败:用户不存在") } }) }) app.listen(8081, () => { console.log("监听8081端口...."); });
额外优化提示
建议改用async/await语法重构代码,不仅更易读,也能更优雅地捕获错误:
// async/await版本的登录接口 app.post('/login', async (req, res) => { const sql = 'SELECT password FROM auth_table WHERE email = ?' try { const data = await new Promise((resolve, reject) => { db.query(sql, req.body.email, (err, queryData) => { if (err) reject(err); else resolve(queryData); }) }); if (data.length > 0) { const hashedPassword = data[0].password; const result = await bcrypt.compare(req.body.password, hashedPassword); return result ? res.json("登录成功") : res.json("登录失败:密码错误"); } else { return res.json("登录失败:用户不存在") } } catch (err) { return res.json("服务器错误"); } })
内容的提问来源于stack exchange,提问作者Chriss Jackson Xiais
相关产品推荐
相关产品推荐

