提问者:小点点

Node.js bcrypt比较问题仅返回false


我想用node.js和MongoDB做我的登录API,当我比较我的输入和db中的传递时,我总是得到false,我读了其他关于StackOverFlow的文章,但没有帮助我。

我想我也发现了问题:当我对密码输入使用哈希来手动检查它时,在每个请求中来自db的是onatherone。

所以也许这就是问题所在,但我不知道该如何解决。我读了很多关于这方面的东西,但仍然无法解决这是我的代码:

const match = await bcrypt.compare(password, user.password, (res) => {console.log(res)}) //false

我的登录api


router.post('/login', body('email').isEmail(), body('password').exists(), async (req, res) => {
    const errors = validationResult(req);

    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() })
    }

    const { email, password } = req.body

    const user = await User.findOne({ email })

    if (!user) {
        return res.status(401).json({ "err": "invalid credentials" })
    }

    // const match = await bcrypt.compare(password, user.password).then(function (res) { console.log(res) })

    const match = await bcrypt.compare(password, user.password);

    console.log(match)

})

下面是register api



router.post("/register", body("email").isEmail(), body("password").isLength({ min: 5 }), body("username").isLength({ min: 1 }), async (req, res) => {
    const { email, username, password } = req.body
    const errors = validationResult(req);
    const saltRounds = 10;

    try {
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() })
        }
        //check if the user exist
        const duplicated = await User.findOne({ email })
        if (duplicated) { return res.status(401).json({ "err": "Email is taken" }) }
        const user = new User({ username, email, password })

        //crypt pass
        user.password = bcrypt.hashSync(process.env.secret, saltRounds);

        //generate token with jwt
        const payload = {
            id: user.id
        }

        jwt.sign({
            payload,
        }, process.env.jwtSecret, { expiresIn: '999h' }, (err, token) => { console.log(token) });
        //save the user
        await user.save()
        res.status(200).send("User Stored")

    } catch (error) {
        res.status(500).send(error.body)
    }

})




共2个答案

匿名用户

尝试为此使用

const match = await new Promise((resolve, reject) => {
  bcrypt.compare(password, user.password, function(error, res){
    if (error) { reject(error); }
    resolve(res);
  })
}) 

匿名用户

您的问题是以错误的方式使用了。似乎您提供了这种方法类型的密钥,但您不应该提供这种密钥。此方法接受hash的值和

因此您基本上需要将注册API代码更改为:

router.post("/register", body("email").isEmail(), body("password").isLength({ min: 5 }), body("username").isLength({ min: 1 }), async (req, res) => {
    const { email, username, password } = req.body
    const errors = validationResult(req);
    const saltRounds = 10;

    try {
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() })
        }
        //check if the user exist
        const duplicated = await User.findOne({ email })
        if (duplicated) { return res.status(401).json({ "err": "Email is taken" }) }
        const user = new User({ username, email, password })

        //crypt pass
        user.password = bcrypt.hashSync(password, saltRounds);

        //generate token with jwt
        const payload = {
            id: user.id
        }

        jwt.sign({
            payload,
        }, process.env.jwtSecret, { expiresIn: '999h' }, (err, token) => { console.log(token) });
        //save the user
        await user.save()
        res.status(200).send("User Stored")

    } catch (error) {
        res.status(500).send(error.body)
    }
}

更具体地说,您可以使用以下方式存储密码:

user.password = bcrypt.hashSync(password, saltRounds);