保存异常的 Mongo 文档

Posted

技术标签:

【中文标题】保存异常的 Mongo 文档【英文标题】:Save a Mongo document with exception 【发布时间】:2015-06-23 12:35:36 【问题描述】:

在平均堆栈应用程序中,我在用户架构中创建一个新用户,然后在文档架构中创建一个新文档

    var UserSchema = new Schema(
            username: String,
            password: String,
            docs: [
                type: mongoose.Schema.Types.ObjectId,
                ref: 'Doc'
            ],
        )
    

    var DocSchema = new Schema(…)
    

    UserSchema.pre('save', function(next) 
        if (this.password) 
            this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
            this.password = this.hashPassword(this.password);
        
        next();
    );

以下代码部分是护照注册,最后我遇到了 newUser.save(); 的问题。推送方法后,如果我不保存用户,则文档 ID 不会显示在用户文档中。但保存用户似乎也改变了散列密码。如果我评论 newUser.save();登录可以正常工作,否则我会输入错误的密码

    passport.use('local-signup', new LocalStrategy(
              usernameField: 'username',
              passwordField: 'password',
              passReqToCallback: true
      ,
      function(req, username, password, done) 

          process.nextTick(function() 

                  User.findOne(
                          username: username
                      , function(err, user) 
                          // if there are any errors, return the error
                          if (err)
                              return done(err);
                          if (user) 
                              return done(null, false, req.flash('signupMessage', 'Username is already taken.'));
                           else 
                              var newUser = new User();
                              newUser.username = username;
                              newUser.password = password;
                              newUser.email = req.body.email;
                              newUser.save(function(err) 
                                  if (err)
                                      throw err;
                                  var doc = new Doc(
                                      user: newUser.username,
                                      docTitle: newUser.username
                                  );
                                  doc.save(function(err)  // create doc
                                      if (err) 
                                          return next(err);
                                       else 
                                          newUser.docs.push(doc); // push doc'id in docs field in user
                                          newUser.save(); // save user after doc'id has been push
                                      ;
                                      return done(null, newUser);
                                  );
                              );

任何帮助将不胜感激

【问题讨论】:

【参考方案1】:

您在 mongoose 预保存中间件中的逻辑是“如果正在保存的文档上有密码,则生成一个盐并对密码进行哈希处理”。因此,如果文档上存在一个已经被加盐和散列的密码,当中间件运行时,它会再次加盐和散列这个预先存在的密码。这就是您无法再次登录的原因;每次保存文档时,您的密码都会更改。

我猜您希望 mongoose 预保存中间件仅在您第一次保存文档时运行。每次保存文档时都会运行预保存中间件。在您可以使用的预保存中间件中的文档上有一个this.isNew 属性可用。这将确保仅在您第一次保存文档时生成密码。

UserSchema.pre('save',  function(next) 
    if (this.password && this.isNew) 
        this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64');
        this.password = this.hashPassword(this.password);
    
    next();
);

【讨论】:

非常感谢@sabrehagen 的清晰解释 - 它就像一个魅力!

以上是关于保存异常的 Mongo 文档的主要内容,如果未能解决你的问题,请参考以下文章

将 Mongo ObjectId 保存到另一个文档中

CosmosDB Mongo 数据库请求保存问题

Spring data Mongo Audit 字段反映在嵌套文档中

Mongo 检查文档是不是已经存在

使用 OpenOffice java api 保存文档会引发异常

在 Solr 中搜索特定 ID