PassportJS - 自定义回调并将Session设置为false

时间:2014-08-06 22:22:07

标签: node.js session express passport.js

是否可以使用自定义回调并禁用会话?在文档中,它显示了如何禁用会话和自定义回调,但我如何组合它们?

app.get('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }

    req.logIn(user, function(err) {

      // I'm getting an error here
      // [Error: Failed to serialize user into session]

      if (err) { return next(err); }
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});

2 个答案:

答案 0 :(得分:16)

请确保您使用的是passport的最新版本(今天为0.2.1)。

请尝试传递{ session: false }作为req.logIn()功能的第二个参数:

app.get('/login', function (req, res, next) {
  passport.authenticate('local', function (err, user, info) {
    if (err) { return next(err); }
    if (!user) { return res.redirect('/login'); }

    req.logIn(user, { session: false }, function (err) {

      // Should not cause any errors

      if (err) { return next(err); }
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
});

原因:

乍一看,在{ session: false }中传递passport.authenticate()似乎是合理的,因为此方法的源代码如下所示:

Authenticator.prototype.authenticate = function(strategy, options, callback) {
  return this._framework.authenticate(this, strategy, options, callback);
};

所以应该能够尊重第二个参数。但是,如果您开始向下钻取函数调用堆栈,您会发现session参数的options属性被完全忽略。我的意思是,

里面没有options.session的引用
this._framework.authenticate(this, strategy, options, callback);

功能

所以基本上你想在req.logIn()函数中传递它。该函数的源代码如下:

req.logIn = function(user, options, done) {
  if (!this._passport) throw new Error('passport.initialize() middleware not in use');

  if (!done && typeof options === 'function') {
    done = options;
    options = {};
  }
  options = options || {};
  var property = this._passport.instance._userProperty || 'user';
  var session = (options.session === undefined) ? true : options.session;

  this[property] = user;
  if (session) { // HERE! It will not try to serialize anything if you pass {session: false}
    var self = this;
    this._passport.instance.serializeUser(user, function(err, obj) {
      if (err) { self[property] = null; return done(err); }
      self._passport.session.user = obj;
      done();
    });
  } else {
    done && done();
  }
}

P.S。请考虑使用npm安装npm install [package-name] --save依赖项,而不是手动创建package.jsonnpm会自动获取最新的稳定版本。

答案 1 :(得分:4)

您是否尝试过直接组合它们? 类似的东西:

passport.authenticate('local', { "session": false }, function(err,user,info){
   //blablabla
});

从护照的源代码,authenticate定义如下:

Authenticator.prototype.authenticate = function(strategy, options, callback) {

所以我不明白为什么你不能使用这两个参数。