You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 01:40:26