Passport: "Error: failed to deserialize user out of session" unwanted on production

Created on 3 Jan 2012  路  13Comments  路  Source: jaredhanson/passport

This is subjective but I believe a deserialization error from a _bad session cookie/reset redis database/other regular production hiccup_ should not totally stonewall the unfortunate user with the problem. As things stand now, as soon as you get a deserialization error you're essentially blacklisted, and the error will be useless information to a typical user.

More desirable production behavior includes any of:

  1. Remove the session information and treat the user as a 'fresh' user who has not logged in
  2. Allow for a configuration option that can override this behavior (eg, gracefulFailure: true)
  3. Provide an override hook for handling failed deserializations, so the developer can at least override

Most helpful comment

Fixed!

You can now invalidate an existing login session by setting user to false or null when calling done inside deserializeUser.

passport.deserializeUser(function(obj, done) {
  done(null, false);  // invalidates the existing login session.
});

Most ORMs set the result to null if the record wasn't found, as is the case with Mongoose. So, this will work as expected if you are deleting user records while they have an active session. In that case, findById sets user to null, which is passed through to Passport and the session will be invalidated.

passport.deserializeUser(function(id, done) {
  User.findById(id, function (err, user) {
    done(err, user);
  });
});

This is fixed in [email protected], which has just been published to the npm registry.

All 13 comments

Agreed. I'm leaning towards option 1 as the proper fix.

strong +1 for one.

+10086 for this issue...

At least allowing the developer to handle the error would be key. +1 for at least exposing that.

+1 on this. Is there a workaround for the issue right now?

Hello guys, any idea when this will be fixed?

Fixed!

You can now invalidate an existing login session by setting user to false or null when calling done inside deserializeUser.

passport.deserializeUser(function(obj, done) {
  done(null, false);  // invalidates the existing login session.
});

Most ORMs set the result to null if the record wasn't found, as is the case with Mongoose. So, this will work as expected if you are deleting user records while they have an active session. In that case, findById sets user to null, which is passed through to Passport and the session will be invalidated.

passport.deserializeUser(function(id, done) {
  User.findById(id, function (err, user) {
    done(err, user);
  });
});

This is fixed in [email protected], which has just been published to the npm registry.

I'm having this exact same issue on version 0.1.12 with passport-facebook.

Thank you! This should definitely find it's way into the documentation.

I would note in the documentation that you have to return null or false. I tried returning undefined instead of null and came here through Google.

A world where null and false are the same but are not the same as undefined makes no sense. The following are true facts of Javascript:

null == false == undefined
null !== false !== undefined

Inventing your own truth table where null == false != undefined makes things unnecessarily confusing.

This working for me, put the next following commands in your terminal:
redis-cli
select 1
FLUSHALL

Just a heads up for folks stumbling across this鈥攊t turns out TypeORM returns undefined and not null. You should do something like (await User.findOne({where: {id: obj.id}})) || false for Passport to work properly.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ksmithut picture ksmithut  路  6Comments

Gibbo3771 picture Gibbo3771  路  4Comments

angel1st picture angel1st  路  5Comments

puradox picture puradox  路  4Comments

ginovski picture ginovski  路  6Comments