PassportJS - Custom Callback and set Session to false

邮差的信 提交于 2019-12-04 19:30:31

问题


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

回答1:


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.




回答2:


Have you tried directly combining them ? Something like :

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

From passport's source code, authenticate is defined as follows :

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

So I don't see why you wouldn't be able to use both parameters.



来源:https://stackoverflow.com/questions/25171231/passportjs-custom-callback-and-set-session-to-false

工具导航Map