使用bcrypt对比密码遇TypeError错误,寻求解决方法
修复方案
核心错误原因
你写的row.getPassword是错误用法,数据库返回的row是普通对象,直接用row.password就能拿到查询到的密码字段,不存在getPassword()这种方法。
其他需修复的问题&代码调整
除了核心错误,还有几个必须修正的坑:
- 直接拼接SQL字符串存在SQL注入风险,必须改用参数化查询
bcrypt.compare是异步函数,不能直接同步赋值给match,得用回调或async/await处理- 错误处理逻辑顺序颠倒,应该先判断数据库查询是否出错
修改后的代码示例:
socket.on('existing user', async function (username, password) { socket.username = validator.escape(username); socket.password = validator.escape(password); db.serialize(function() { // 用参数化查询避免SQL注入 const getPassword = 'SELECT password FROM users WHERE username = ?'; db.get(getPassword, [socket.username], async function(err, row) { // 先处理数据库查询错误 if (err) { console.log(err); return; } // 必须判断是否查到用户(用户名不存在时row为null) if (!row) { socket.emit('user-not-found'); // 可新增用户名不存在的提示事件 return; } try { // bcrypt.compare是异步操作,用await处理 const match = await bcrypt.compare(socket.password, row.password); match ? socket.emit('redirect') : socket.emit('passwordsnotmatch'); } catch (compareErr) { console.log('密码对比出错:', compareErr); } }); }); });
补充说明
- 参数化查询里的
?是占位符,后面的数组[socket.username]会自动转义内容,彻底避免注入风险 - 若不想用async/await,也可以用bcrypt的回调写法:
bcrypt.compare(socket.password, row.password, function(err, match) { if (err) { console.log(err); return; } match ? socket.emit('redirect') : socket.emit('passwordsnotmatch'); });
内容的提问来源于stack exchange,提问作者Wager2000
相关产品推荐
相关产品推荐

