Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PassportJS - Custom Callback and set Session to false

Is it possible to use custom callback and disable session? In the documentation it shows how to disable session and custom callbacks, but how do i combine them?

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);
});
like image 659
YarGnawh Avatar asked Aug 06 '14 22:08

YarGnawh


1 Answers

Please make sure you use newest version of passport (which is 0.2.1 for today).

Please try passing { session: false } as a second parameter of your req.logIn() function:

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);
});

Reason:

At first glance, passing { session: false } in passport.authenticate() seems to be reasonable because sourcecode of this method looks like:

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

So it should be able to honor second parameter. But if you start to drill down the function call stack, you realize that session attribute of options parameter is being disregarded completely. I mean, there is no reference to options.session inside

this._framework.authenticate(this, strategy, options, callback);

function.

So basically you want to pass it in req.logIn() function. Source code of this function is as follows:

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. Please consider installing your npm dependencies using npm install [package-name] --save instead of creating package.json manually. npm will automatically fetch newest stable version.

like image 135
marekozw Avatar answered Sep 30 '22 22:09

marekozw