首页 > 解决方案 > Bcrypt compareSync 函数抛出非法参数错误

问题描述

我正在尝试通过在发布请求中获取用户名和密码来登录用户。我这样做是为了让每个用户都有唯一的用户名。但是当我尝试通过将请求中的密码与返回的哈希密码进行比较来检查用户是否输入了正确的密码时从数据库中,所以如果它们匹配我可以发回一个令牌我得到这个错误:非法参数:字符串,未定义。

这是代码:

router.post('/login', (req, res) => {

    User.find({ username: req.body.username }, (err, data) => {

        var passwordIsValid = bcrypt.compareSync(req.body.password, data.password);
        if (err) return res.send(err);
        if (data.length === 0 || !passwordIsValid) return res.json({ msg: "Invalid credentials." });
        var token = jwt.sign({ id: user._id }, 'supersecret', {
            expiresIn: 86400 // 24 hours

        });

        res.json({ auth: true, token: token });

    });

});

标签: node.jsbcrypt

解决方案


这里的代码片段我没看懂var token = jwt.sign({ id: user._id }, 'supersecret', {user._id从哪里来的?此行中的更改应该可以解决,如果成功,请执行测试建议。

router.post('/login', (req, res) => {

    User.find({ username: req.body.username }, (err, data) => {

        var passwordIsValid = bcrypt.compareSync(req.body.password, data.password);
        if (err) return res.send(err);
        if (!passwordIsValid) return res.json({ msg: "Invalid credentials." });
        var token = jwt.sign({ id: data._id }, 'supersecret', {
            expiresIn: 86400 // 24 hours

        });

        res.json({ auth: true, token: token });

    });

});

如果您更喜欢使用 async / await 进行测试。

router.post('/login', async (req, res) => {

    const user = await User.find({ username: req.body.username })
    if(!user){
        return res.send({Error: 'User does not exist'})
    }
    if(!await bcrypt.compare(req.body.password, user.password)){
        return res.send({msg: 'Invalid credentials.'})
    }

    const token = jwt.sign({id: user._id}, 'supersecret',{
        expiresIn: 86400
    })
    res.json({ auth: true, token: token });

});

后来我发现这个错误而不是 user._id 它是 data._id 但它仍然没有工作原来数据是一个对象数组,因为每个用户名都是唯一的,它总是只有一个对象保存有关用户的信息给定用户名,所以为了访问用户密码,我需要写 data[0].password 而不是 data.password。


推荐阅读