是修改并预存mongoose...Nodejs

问题描述 投票:0回答:4

嗨,我只想在密码更改时使用哈希密码保存,所以我在预保存中使用了 isModified 函数,但即使我更改了密码,它也总是返回 false。我尝试这样做的原因是因为我不想在更改其他属性时更改并保存我的密码。

router.post('/changepw', isAuthenticated, function (req, res, next) {
    User.findOneAndUpdate({_id: req.user._id}, {$set: req.body},{ new: true }, function (err, user){

        if (err) {
          return err;
        } 
        else {

          if (req.body.password) {
            user.password = req.body.password;
            user.save();
          } else { 

          }

        }
        res.redirect('/profile');
    });
});

就像这里,当我更改我的毕业值时,我不想更改我的密码。

router.post('/edit', isAuthenticated, function (req, res, next) {
    User.findOneAndUpdate({
        _id: req.user._id
    }, {
        $set: {
            name: req.body.name,
            phone: req.body.phone,
            classc: req.body.classc,
            major: req.body.major,
            minor: req.body.minor,
            linkedin: req.body.linkedin,
            bio: req.body.bio
        }
    }, {
        new: true
    }, function (err, user, done) {

        if (err) {
            return err;
        } else {

            if (typeof req.body.graduated == 'undefined') {
                user.graduated = false;


            } else if (typeof req.body.graduated == 'string') {

                user.graduated = true;

            }

            user.save();
        }
        res.redirect('/profile');
    });
});
userSchema.pre('save', function(next) {
console.log(this.isModified('password'));                                                                                                                                        
    if(this.password && this.isModified('password')){                                                                                                                                                                                                                                                                                      
        this.password  = bcrypt.hashSync(this.password, bcrypt.genSaltSync(8),null);                                                                                                             
    }

    next()                                                                                                                                                                     
}); 

有什么建议吗?

node.js mongoose
4个回答
10
投票

请注意,当您使用

findAndUpdate()
方法时,不会触发预保存挂钩。使用新的钩子检查 Mongoose 文档:http://mongoosejs.com/docs/middleware.html#notes.


9
投票

试试这个

userSchema.pre('save', async function (next) {
  // Only run this function if password was moddified (not on other update functions)
  if (!this.isModified('password')) return next();
  // Hash password with strength of 12
  this.password = await bcrypt.hash(this.password, 12);
  //remove the confirm field 
  this.passwordConfirm = undefined;
});

4
投票

findOneAndUpdate()
已经更新了
user
,因此在您提供的回调函数中
user
已经是最新的。当您在该回调中调用
user.save()
时,将调用 pre
save()
钩子,但
isModified('password')
将为 false。

如果您使用

req.body
提供新密码,该密码将以未散列的方式存储在数据库中,因为“Pre 和 post
save()
钩子不会在
update()
findOneAndUpdate()
等上执行”。 (参见文档)。如果你再比较
req.body
user
中的密码,它们将是相同的,你无法决定是否用
save()
触发哈希函数。

保留之前的

save()
挂钩,并以
findById()
save()
的组合进行更新:

  User.findById(req.user._id, (err, user) => {
    if (err)
      handleYourErrorAndLeave(err)
  
    // Update all user attributes which are different or missing from user with values from req.body
    Object.assign(user, req.body)

    // Save the updated user object.
    // pre save() hook will be triggered and isModified('password') should be correct
    user.save()
      .then(savedUser => {
        res.redirect('/profile')
      }) 
  })

0
投票

最好从模型中操纵密码。您可以在此处根据需要更新或持续更新密码以及其他值。

// Encrypt password before saving into database
userSchema.pre("save", async 
 function(next) {
 if (!this.isModified("password")) {
  return next();
 }
 const salt = await bcrypt.genSalt(10);
 const hashedPassword = await bcrypt.hash(this.password, salt);
 this.password = hashedPassword;
 next();
});
© www.soinside.com 2019 - 2024. All rights reserved.