0

I am trying to use passportjs in my nodejs app with express4. For testing purpose, I am using session-file-store to keep session.

The way I set up the session and passportjs :

this.app.use(session({
  secret: process.env.SESSION_SECRET || configuration.session_secret,
  store: new fileStore(),
  resave: false,
  saveUninitialized: false
}));

// config authentication
this.app.use(passport.initialize());
this.app.use(passport.session());
// Configure Passport
passport.use('local-login', new localStrategy.Strategy(
    (username, password, done) => {
      Services.users.authenticatePromise(username, password).then(
          function(token) {
            done(null, token);
          },
          function(err) {
            done(null, false, err);
          },
      ).done();
    },
));
    // Serialize user in session
passport.serializeUser((token: AccessToken, done) => {
  let user = {
    _token: token.accessToken,
    _expiryInAt: token.expiryInMs + new Date().getTime(),
  };
  done(null, user);
});

passport.deserializeUser((sessionUser, done) => {
  done(null, sessionUser);
});

However, the issue I am having is that if I don't write anything into the session before user is logged in, passportjs works fine. However if I am trying to write some data into session like shopping cart details, then passportjs would not be able to serialize the user token into the session store any more. so login cannot be successful.

What am I missing?

rzhomx
  • 85
  • 1
  • 12
  • Are you doing `req.session = { ... }` or something similar? I.e. overwriting the entire session object with something new. – robertklep May 30 '17 at 08:32
  • no, I did something like : ```if (!req.session['basket']) { req.session['basket'] = {}; }``` – rzhomx May 30 '17 at 08:39
  • Ah sorry, that shouldn't be the issue anyway, since it fails to serialize. Can you add the implementations for `passport.serializeUser/deserializeUser` to your question? Also, what does _"would not be able to serialize"_ mean, exactly? – robertklep May 30 '17 at 08:46
  • where is your serialize and deserialise functions . write their code also here – Asad May 30 '17 at 12:13
  • Also, what does "would not be able to serialize" mean, exactly? I meant if I checked the session file, the passport session is not written at all. – rzhomx May 30 '17 at 13:32

1 Answers1

2

you have a couple of things wrong with your code that I can see.

first, serializeUser should take an object and return a string (typically a unique id or database key). Your function currently takes a string and returns an object; that's backwards.

second, deserializeUser should take a string and return a user object. Your function currently takes an object and returns that same object.

finally ,serializeUser and deserializeUser must be inverses of each other; meaning, passport can call deserializeUser(serializeUser(user)) and get back the original user object.

So you're going to want something like this:

passport.serializeUser((user, done) => {
  return user.id;
});

passport.deserializeUser((id, done) => {
  getUserFromDatabase({id: id}, function(err, user) {
    if (err) {
      done(err, null); // something went wrong; return error
    } else if (!user) {
      done(null, false); // no user found; return `false`
    } else {
      done(null, user);  // return user
    }
  });
});

for more info see here: Understanding passport serialize deserialize

Dan O
  • 6,022
  • 2
  • 32
  • 50
  • You are right. it is not the best practice for sure but I think it is not the reason for the issue I am seeing. firstly,when I don't write anything into the session before login, this serializeUser/deserializeUser works fine. it can serialize the user into the session store and deserialise it. And I am just trying to use api token instead of user id with passportjs, any better solution I can take? – rzhomx May 30 '17 at 14:25