首页 > 解决方案 > 仅在 NodeJS 和 ExpressJS 中满足条件后更新密码

问题描述

我正在尝试创建一个组件,在该组件中我向用户请求他的当前密码和两个需要匹配以更改其密码的 iinput。

到目前为止,我创建了如下路线:

// @route       POST api/profiles/edit-password
// @description Update user password
// @access      Private
// @task        ALMOST DONE - NEEDS TO AVOID PASSWORD UPDATING IF NULL
router.post(
  '/edit-password',
  [
    auth,
    [
      check('old_password', 'Old Password is required')
        .not()
        .isEmpty(),
      check('old_password', 'Old Password does not match')
        .exists(),
      check('password', 'New Password is required')
        .not()
        .isEmpty(),
      check('new_password', 'Confirm Password is required')
        .not()
        .isEmpty()
    ]
  ],
  async (req, res) => {
    const errors = validationResult(req);
    // Check for errors
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    // Destructure
    const {
      old_password,
      password,
      new_password,
    } = req.body;

    // Build profile object
    const profileFields = {};
    profileFields.user = req.user.id;
    if (password === new_password) {
      // Encrypt Password
      passwordEncrypt = password;
      const salt = await bcrypt.genSalt(10);
      profileFields.password = await bcrypt.hash(passwordEncrypt, salt);
    }

    try {

      let formOldPassword = old_password; // req.body.old_password can be used as well.
      let loggedPassword = await User.findById(req.user.id).select('password');

      // Old password input with password stored in DB
      const isMatch = await bcrypt.compare(formOldPassword, loggedPassword);

      console.log(isMatch ? 'yes' : 'no');

      // In case old password input does not match with password stored in DB, prevent from updating password
      if (!isMatch) {
        return res
          .status(400)
          .json({ errors: [{ msg: 'Invalid credentials' }] });
      }

      let profile = await User.findByIdAndUpdate(req.user.id, profileFields, { new: true });

      return res.json(profile);


    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server error');
    }
  }
);

我从功能组件中的表单传递三个输入,这些输入是:

之后,我构建了一个空对象,我将使用它来更新与请求它的用户相对应的所述值。之后,我设置了一个条件,如果 new_password 和 confirm_password 都匹配,它应该使用哈希加密密码(这是我假设错误的原因;我可能错了):

if (password === new_password) {
      // Encrypt Password
      passwordEncrypt = password;
      const salt = await bcrypt.genSalt(10);
      profileFields.password = await bcrypt.hash(passwordEncrypt, salt);
    }

然后我开始调用数据库以获取与已登录用户对应的密码,并将其存储的密码与从表单提交的数据进行比较:

let formOldPassword = old_password; // req.body.old_password can be used as well.
let loggedPassword = await User.findById(req.user.id).select('password');

// Old password input with password stored in DB
const isMatch = await bcrypt.compare(formOldPassword, loggedPassword);

现在两个输入必须匹配,但如果它们不匹配,则返回 400 http 错误。如果到目前为止一切都成功,请更新已登录的用户数据。

// In case old password input does not match with password stored in DB, prevent from updating password
if (!isMatch) {
  return res
    .status(400)
    .json({ errors: [{ msg: 'Invalid credentials' }] });
}

let profile = await User.findByIdAndUpdate(req.user.id, profileFields, { new: true });

return res.json(profile);

我在控制台中得到的意外(错误)输出是这样的:

Illegal arguments: string, object

关于如何解决这个问题的任何想法?

标签: node.jsreactjsexpressmern

解决方案


您正在将字符串新密码与对象(而不是字符串)进行比较。在下面尝试并打印旧密码

   try {
            const userObj = await User.findById(req.user.id);
            const oldPassword = userObj.password;
             console.log("OLD password" + password);
            //Then do your comparision logic
        } catch (err) {
            console.log('error occured' +err);   
        }

推荐阅读