3

在一些帮助下,我得到了以下代码来承诺一个 passport.js 登录策略。

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 可以使用它。

是否可以处理两个失败(不是错误)路径?


更新:

正如评论中所问的那样,我在 Github 上创建了一个问题,并且(非常迅速地)在 Bluebird v2.0 中添加了此功能

https://github.com/petkaantonov/bluebird/issues/219

4

3 回答 3

4

利用:

.nodeify(done, {spread: true});

这允许将多个参数传递给“完成”回调。

更多信息:

蓝鸟节点化文档

于 2015-06-05T08:51:19.017 回答
4

我添加这个答案是为了展示如何.nodeify(done, {spread: true})在原始示例中使用(如其他答案/评论中所述)。

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) {
          return [false, { message: '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 {
        return [false, { message: 'Incorrect password.' }]; <---------------
        //should be equivalent to:
        // return done(null, false, {message:'something else'};
      }
    })
    .nodeify(done, {spread: true});
});
于 2015-08-12T22:28:07.923 回答
1

目前,没有办法做到这一点.nodeify,你当然可以手动做到这一点.then

.then(function(result){
     done(/*whatever arguments you need*/);
},function(failure){
     done(/* failure argumnets */);
});
于 2014-05-28T20:01:19.963 回答