猫鼬|预保存挂钩中的对象更改不会保存到db

时间:2017-06-19 20:22:47

标签: javascript node.js mongoose bcrypt

我遇到了一个问题,我无法解决。 我会尝试将其描述为尽可能有意义和简单。 这是我的方法,它处理发布请求并保存数据:

app.post('/users/', (req, res) => {
    let body = _.pick(req.body, ["email", "password"]);
    let user = new User(body);

    user.save().then(
        user => res.json(user),
        err => res.send(err)
    )
});

当我将新用户保存到数据库时,这个预保存挂钩会触发:

userSchema.pre('save', function(next) {
    var user = this;

    if(user.isNew){
        bcrypt.genSalt(10, (err, salt) => {
            bcrypt.hash(user.password, salt, (err, hash) => {
                user.password = hash;
                console.log(user);
                next();
            })
        })
    }
    next();
})

对于POST正文中的此输入:

{
    "email": "example@example.com",
    "password": "somepass"
}
来自预保存挂钩日志的

console.log:

{ __v: 0,
  email: 'example@example.com',
  password: '$2a$10$tWuuvw.wGicr/BTzHaa7k.TdyZRc5ADDV0X1aKnItvVm6JYVe5dsa',
  _id: 59482e8136fd8d2bf41e24b7 
}

然而在db中我得到了:

{
    "_id" : ObjectId("59482e8136fd8d2bf41e24b7"),
    "email" : "example@example.com",
    "password" : "somepass",
    "__v" : 0
}

显然没有保存用户对象的更改,而在save()方法中,我仍然使用带有未使用密码的旧值。这是为什么?如何从预存挂钩中进行更改以进行存储?

1 个答案:

答案 0 :(得分:0)

问题是,即使密码需要异步加密,您也始终在next()阻止后调用if

将您的代码更改为仅对现有user文档执行此操作:

if(user.isNew){
    bcrypt.genSalt(10, (err, salt) => {
        bcrypt.hash(user.password, salt, (err, hash) => {
            user.password = hash;
            console.log(user);
            next();
        })
    })
}
else {
    next();
}