首页 > 解决方案 > 我希望我的 pre('save') mongoose 函数只运行一次

问题描述

我不知道标题中的确切要求是否可能,但如果不是;我真的很感激另一种解决方案。

我有这种猫鼬的预保存方法

ownerSchema.pre("save", function(next) {


 const owner = this;
  bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash(owner.password, salt, function(err, hash) {
      // Store hash in your password DB.
      owner.password = hash;
      next();
    });
  });
});

当我保存新用户(所有者)时,成功创建了一个哈希,一切都很好>

当我登录时出现问题。当我登录时,我使用如下的猫鼬自定义方法生成 jwt

ownerSchema.methods.generateToken = function(cb) {
  var owner = this;
  var token = jwt.sign(
    {
      _id: owner._id,
      username: owner.username,

      email: owner.email,
      category: owner.category === 0 ? false : true,
      phones: owner.phones,
      address: owner.address
    },
    config.SECRET,
    { expiresIn: "1h" }
  );
   owner.token= token;

  owner.save(function(err,owner){
    if(err) return cb(err);
    cb(null,owner);
  })
};

如您所见,我生成令牌以将其发送到“res”中,同时我将新令牌添加到数据库中的记录中。到目前为止一切正常,响应成功返回>

但!!当我在生成令牌函数中执行 save() 以保存令牌>>之前的 pre(save) 函数再次运行时,为密码字段生成了一个新的哈希。

当我再次尝试登录时,在第一次登录时生成令牌时,密码已经从调用预保存哈希函数更改。

解决此问题的任何解决方法?

标签: node.jsmongodbmongoosemongoose-schemamern

解决方案


您可以在“密码”字段上使用isModified方法。

我以这种方式使用它,只有在更改密码属性时才运行 bcrypt:

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

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

推荐阅读