Express-validator在asynchronousvalidation中不返回对象

我正在使用express-validator和passport.jsvalidationlogin表单,使用本地策略:

login: function() { passport.use('local-login', new LocalStrategy({ passReqToCallback: true }, function(req, username, password, done) { req.check('username', 'Incorrect user and/or password.').doesUserExists(password); req.check('password', 'Password cannot be empty.').notEmpty(); req.asyncValidationErrors(true) .then(function(user) { return done(null, user); }) .catch(function(errors) { if (errors) return done(null, false, req.flash('error', errors)); }); } )); } 

函数doesUserExists()是一个自定义的asynchronousvalidation,为用户查询,比较数据库中散列密码提供的密码并parsing:

 doesUserExists: function(username, password) { return new Promise(function(resolve, reject) { User.findOne({ username: username }) .then(function(user) { if (user) return user; if (!user) reject(user); }) .then(function(user) { user.comparePassword(password, function(error, isMatch) { if (isMatch) return user; else reject(user); }); resolve(user); }) .catch(function(error) { if (error) reject(error); }); }); } 

到目前为止,它是完美的工作,除非当用户和密码匹配,并承诺解决,没有对象(用户)返回到req.asyncValidationErrors()函数,防止其.then()块redirect到用户资料。

我必须补充一点,我对承诺很陌生,不确定我期待的事情是否会发生。 也许一些关于它是如何工作的误解是导致我认为是错误的。

更新

现在,我决定为validation的用户/密码进行另一个数据库查询:

 req.asyncValidationErrors(true) .then(function() { User.findOne({ username: username }) .then(function(user) { return done(null, user); }); }) .catch(function(errors) { if (errors) { return done(null, false, req.flash('error', errors)); } }); 

额外的数据库查询不优雅,但…

如果您可以返回User.find返回的Promise,则不需要创build新的Promise:

 doesUserExists: function(username, password) { return User.findOne({ username: username }) .then(function(user) { if (user) { // Also here is a mistake because we can't return inside // the comparePassword callback, and that's why user is not get back user.comparePassword(password, function(error, isMatch) { if (isMatch) return user; else throw new Error('my error'); }); } else throw new Error('my error'); }); } // Now use it as follows req .check('username', 'Incorrect user and/or password.') .doesUserExists(username, password) .then(function(user){/* user authenticated */}) .catch(function(error){/* user not atuhenticated */}); 

所以我想你可以稍后比较密码和问题解决:

 doesUserExists: function(username, password) { return User.findOne({ username: username }) .then(function(user) { if (user) return user; else throw new Error('my error'); }); } // Now use it as follows req .check('username', 'Incorrect user and/or password.') .doesUserExists(username, password) .then(function(user){ /* From here, user was found */ user.comparePassword(password, function(error, isMatch) { if (isMatch){ /* Do whatever with the user authenticated */ } else { /* Do whatever you want when password don't match */ } }); }) .catch(function(error){/* user not found */}); 

如果你正在做一个以上的asynchronousvalidation,我build议你使用Promise.all()来执行并行的asynchronous函数。