【问题标题】:Mongoose | Object changes in pre-save hook are not saved to db猫鼬 |预保存挂钩中的对象更改不会保存到数据库
【发布时间】:2017-06-20 05:28:25
【问题描述】:

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

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() 方法中,我仍然使用带有未散列密码的旧值。这是为什么?以及如何从要存储的预保存挂钩中进行更改?

【问题讨论】:

    标签: javascript node.js mongoose bcrypt


    【解决方案1】:

    问题是你总是在if 块之后调用next(),即使密码需要异步加密。

    将您的代码更改为仅对现有的 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();
    }
    

    【讨论】:

    • 我简直不敢相信自己不是自己想出来的。这太愚蠢了。非常感谢你,JohnnyHK!最好的问候!
    • 对于未来的任何人,如果您使用猫鼬预保存,请不要使用异步,这个答案提示了我。
    猜你喜欢
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2013-08-14
    • 2018-03-04
    • 2018-07-25
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多