在Mongoose中使用错误的validation器进行路由

我使用Postman来testing路由,并且这个路由返回user.save((err)=>{})之后的err消息,表示密码太长。 它使用我创build的passwordValidator但我显然没有在Schema中为此路由调用它。

我究竟做错了什么?

mongoose中的用户模式:

  const userSchema=new Schema({ email: { type: String, required: true, unique: true, lowercase: true, validate: emailValidators}, username: { type: String, required: true, unique: true, lowercase: true, validate: usernameValidators}, bio: { type:String,default:null,validate:bioValidators}, location: {type:String, default:null}, gender: {type:String,default:null,validate:genderValidators}, birthday: { type:String,default:null}, password: { type: String, required: true,validate: passwordValidators} }); 

路线:

 router.put('/editProfile',(req,res)=>{ if(!req.body.bio){ res.json({success:false,message:"No bio provided"}); } else{ if(!req.body.location){ res.json({success:false,message:"No location provided"}); } else{ if(!req.body.gender){ res.json({success:false,message:"No gender provided"}); } else{ if (!req.body.birthday) { res.json({success:false,message:"No birthday provided"}); } else{ User.findOne({_id:req.decoded.userId},(err,user)=>{ if(err){ res.json({success:false,message:"Something went wrong: "+err}); } else{ if(!user){ res.json({success:false,message:"User not found"}); } else{ user.bio=req.body.bio; user.location=req.body.location; user.gender=req.body.gender; user.birthday=req.body.birthday; user.save((err)=>{ if(err){ res.json({success:false,message:'Something went wrong: '+ err}); //returns this } else{ res.json({success:true,message:"Account updated !"}); } }); } } }); } } } } }); 

编辑

这是密码validation程序数组

 const passwordValidators = [ { validator: passwordLengthChecker, message: 'Password must be at least 5 characters but no more than 40' }, { validator:validPassword, message: 'Must have at least one uppercase, lowercase, special character, and number' } ]; 

和跳棋

 let passwordLengthChecker = (password)=>{ if (!password) { return false; } else{ if(password.length<5 || password.length>40){ return false; } else{ return true; } } }; let validPassword = (password)=>{ if (!password) { return false; } else{ const regExp = new RegExp(/^(?=.*?[az])(?=.*?[AZ])(?=.*?[\d])(?=.*?[\W]).{8,35}$/); return regExp.test(password); } }; 

正如你可以看到它使用passwordLengthChecker,但它不应该

编辑N°2

我刚刚意识到我在这个模式下面有这个中间件

 userSchema.pre('save', function(next){ if(!this.isModified('password')) return next(); bcrypt.hash(this.password, null, null, (err,hash)=>{ if(err) return next(err); this.password=hash; next(); }); }); 

这是否意味着这个函数每次使用save()都会运行?

这里是问题,你提供biolocationgenderbirthday但不是密码。 当你不声明密码时,它的length将等于0 。 这就是为什么你得到错误。 长度可以从540

 else{ user.password=req.body.password; //I added user.password here, this is what you should do user.bio=req.body.bio; user.location=req.body.location; user.gender=req.body.gender; user.birthday=req.body.birthday; user.save((err)=>{ if(err){ res.json({success:false,message:'Something went wrong: '+ err}); //returns this } else{ res.json({success:true,message:"Account updated !"}); } }); } 

在这里更新

如果你只是要更新biolocationgenderbirthday然后使用save()函数是错误的。 你需要使用findOneAndUpdate()函数。

 User.findOneAndUpdate({_id:req.decoded.userId}, { $rename : {gender: 'male' , bio : 'somethingElse'}}, {new: true}, function(err, user){ if(err) throw err; else{ console.log("done : " + user.gender); } }); 

另请参阅findOneAndUpdate 及其使用的操作符

所以我认为bcrypt函数妥协了Mongoose save()函数,现在在Mongoose doc中我find了另一个解决scheme。

 User.findByIdAndUpdate(req.decoded.userId,{$set:{bio:req.body.bio, location:req.body.location, gender:req.body.gender, birthday:req.body.birthday}},{new:true},function(err,user){ if(err){ res.json({success:false,message:"Something went wrong: "+err}); } else{ if(!user){ res.json({success:false,message:"User not found"}); } else{ res.json({success:true,user:user}); } } });