【发布时间】:2014-07-18 04:56:52
【问题描述】:
With a little help我已经到了以下代码来承诺a passport.js login strategy.
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var Promise = require('bluebird');
var bcrypt = require('bcrypt');
var db = require('./db').db; //users are stored in mongo
//I'm using bluebird.js for promises
var users = Promise.promisifyAll(db.users);
var compare = Promise.promisify(bcrypt.compare);
// This strategy is used by passport to handle logins
module.exports.localStrategy = new LocalStrategy(function(username, password, done) {
users.findOneAsync({username: username}).bind({})
.then(function(user) {
if (!user) {
throw new NoMatchedUserError('Incorrect username.');
//should be equivalent to:
// return done(null, false, {message:'something'});
}
this.user = user;
return compare(password, user.password);
})
.then(function(isMatch) {
if (isMatch) {
return this.user;
//is equivalent to:
// return done(null, this.user);
}
else {
throw { message: 'Incorrect password.' };
//should be equivalent to:
// return done(null, false, {message:'something else'};
}
})
.nodeify(done);
});
通过调用nodeify(done),我可以处理密码匹配的路径,但我不知道如何传递可选的第三个参数以便passport.js 可以使用它。
是否可以处理两个失败(不是错误)路径?
更新:
根据 cmets 的要求,我在 Github 上创建了一个问题,并且(非常迅速地)在 Bluebird v2.0 中添加了此功能
【问题讨论】:
-
哇,这实际上是 nodeify 的一个很好的用例,很多节点 API 需要多个参数。打开一个问题,我们会处理它(意思是,我会在他写之前给 petka 出问题,如果他不写,我会写它,他会重写它以提高性能)ץ
-
嗯,您的原始代码实际上看起来还不错。您需要一个可以解决三种可能状态的 Promise:错误、已识别用户和登录问题。您可以尝试不同的错误类型,它们的处理方式不同,但您不能在这里简单地使用
nodeify。 -
@BenjaminGruenbaum 我看不出这怎么可能,如果你用数组解决承诺,你怎么知道 nodeify 应该用数组作为结果调用它还是为 nodeback 传播数组? Passport 在这里违反了节点回调约定并查看结果:P
-
@Esailija 一个解决方案是第二个参数。
-
@BenjaminGruenbaum 听起来像脚枪
标签: javascript node.js promise passport.js bluebird