如何使用 bcrypt 同时散列两个密码?

How to hash two password simultaneously using bcyrpt?

我正在尝试使用两个密码获取登录页面。只有一个密码,代码运行良好,但当我添加另一个密码时,它会抛出错误 "parallel Save Error"。

[0] (node:16516) UnhandledPromiseRejectionWarning: ParallelSaveError: Can't save() the same
doc multiple times in parallel. Document: 5e703180c90fbc40848fcfca

[0] (node:16516) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated 
either by throwing inside of an async function without a catch block, or by rejecting a promise which 
was not handled with .catch(). (rejection id: 2)

[0] (node:16516) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated.
In the future, promise rejections that are not handled will terminate the Node.js process with a non- 
zero exit code.

这是我的 user.js 脚本:

const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const config = require('config');
const jwt = require('jsonwebtoken');
const User = require('../../models/User');

router.post('/', (req, res,) => {
const { name, email, password1, password2 } = req.body;

if(!name || !email || !password1 || !password2) {
return res.status(400).json({ msg: 'Please enter all fields' });
}

User.findOne({ email })
.then(user => {
  if(user) return res.status(400).json({ msg: 'User already exists' });

  const newUser = new User({
    name,
    email,
    password1,
    password2
  });

  // Hash
  bcrypt.genSalt(10, (err, salt) => {
    bcrypt.hash(newUser.password1, salt , (err, hash) => {
      if(err) throw err;
      newUser.password1 = hash;
      newUser.save()
        .then(user => {
          jwt.sign(
            { id: user.id },
            config.get('jwtSecret'),
            { expiresIn: 3600 },
            (err, token) => {
              if(err) throw err;
              res.json({
                token,
                user: {
                  id: user.id,
                  name: user.name,
                  email: user.email
                }
              });
            }
          )
        });
     })
  })


  // Create salt & hash
  bcrypt.genSalt(10, (err, salt) => {
    bcrypt.hash(newUser.password2, salt, (err, hash) => {
      if(err) throw err;
      newUser.password2 = hash;
      newUser.save()
        .then(user => {
          jwt.sign(
            { id: user.id },
            config.get('jwtSecret'),
            { expiresIn: 3600 },
            (err, token) => {
              if(err) throw err;
              res.json({
                token,
                user: {
                  id: user.id,
                  name: user.name,
                  email: user.email
                }
              });
            }
          )
        });
     })
   })
 })
});

module.exports = router;

下面是 Authentication.js

的代码
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const config = require('config');
const jwt = require('jsonwebtoken');
const auth = require('../../middleware/auth');


// User Model
const User = require('../../models/User');

router.post('/', (req, res) => {
const { email, password1, password2 } = req.body;

// for validation
if(!email || !password1 || !password2) {
return res.status(400).json({ msg: 'Please enter all fields' });
}

// Check if user exists
User.findOne({ email })
.then(user => {
  if(!user) return res.status(400).json({ msg: 'User Does not exist' });

  // Validation of password
  bcrypt.compare(password1, user.password1)
    .then(isMatch => {
      if(!isMatch) return res.status(400).json({ msg: 'Invalid credentials' });

      jwt.sign(
        { id: user.id },
        config.get('jwtSecret'),
        { expiresIn: 3600 },
        (err, token) => {
          if(err) throw err;
          res.json({
            token,
            user: {
              id: user.id,
              name: user.name,
              email: user.email
            }
          });
        }
      )
    })
  bcrypt.compare(password2, user.password2)
    .then(isMatch => {
      if(!isMatch) return res.status(400).json({ msg: 'Invalid credentials' });

      jwt.sign(
        { id: user.id },
        config.get('jwtSecret'),
        { expiresIn: 3600 },
        (err, token) => {
          if(err) throw err;
          res.json({
            token,
            user: {
              id: user.id,
              name: user.name,
              email: user.email
            }
          });
        }
      )
    })
 }) 
})

router.get('/user', auth, (req, res) => {
User.findById(req.user.id)
.select('-password1, -password2')
.then(user => res.json(user));
});

module.exports = router;

我只得到 password2 作为散列密码。

password1:"ddd"
password2:"a$PQhBiDtelKoRspAFn7BW0OuI0pnAyDl.DQSag6bBvYdlirBZM/oAq"

我需要做什么来消除这些错误?

我得到了上述问题的答案... 只需要更改 user.js 中的以下部分。无需创建哈希两次。

 bcrypt.genSalt(10, (err, salt) => {
    bcrypt.hash(newUser.password1, salt , async (err, hash) => {
      bcrypt.hash(newUser.password2, salt, async (err, hash) => {
      if(err) throw err;
      newUser.password1 = hash;
      newUser.password2 = hash;
      await newUser.save()
      ...
      ...

同样需要在 athentication.js 脚本中执行。

 bcrypt.compare(password1, user.password1)
  bcrypt.compare(password2, user.password2)
    .then(isMatch => {
      if(!isMatch) return res.status(400).json({ msg: 'Invalid credentials' 
   });
      jwt.sign(
        { id: user.id },
        ...
        ...

我觉得把加密密码的方法写在model.js里用User导出到route.js 或任何它的名称以获得更好和更干净的代码,以便您可以根据需要使用您的方法。