jaredhanson / passport

Simple, unobtrusive authentication for Node.js.
https://www.passportjs.org?utm_source=github&utm_medium=referral&utm_campaign=passport&utm_content=about
MIT License
22.97k stars 1.24k forks source link

deserializeUser not called when user session shared between 2 apps #612

Closed jhowarth15 closed 7 years ago

jhowarth15 commented 7 years ago

Been struggling with this for a while, so would appreciate any help!!

I'm trying to deserialize users and authenticate them on my wiki app localhost:8000, when they are logged in with passport on my main express app localhost:3000.

Everything works fine on the main app side with log ins and persisted session auth with passportjs. However my wiki app never calls deserializeUser to identify the user in req.user.

In the wiki app, I use the same express session secret as the main app's express session and cookie.secure is set to false, so shouldn't be an issue.

The wiki app does not have any passport local login method, as I just want to use the cookie set by passport in the main app and login from the main app too.

I think its a session sharing issue, or something under the hood of passport that I'm missing.

This is my wiki session setting:

app.use(session({
  name: 'wikijs.sid',
  secret: 'thisIsTopSecretSoDontTellAnyone',
  resave: false,
  saveUninitialized: false,
  cookie : { path: '/', secure : false, maxAge : (4 * 60 * 60 * 1000), sameSite: false } // 4 hours
}))
app.use(passport.initialize())
app.use(passport.session())

app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
  res.send(200);
} else {
  next();
 }
});

A lot of the stuff I've thrown in there is unnecessary, I just threw it in to try and solve this issue.

The main app session setting looks like this:

app.use(expressSession({
  name: 'wikijs.sid',
  secret: 'thisIsTopSecretSoDontTellAnyone',
  resave: false,
  saveUninitialized: false,
  cookie : { path: '/', secure : false, maxAge : (4 * 60 * 60 * 1000), sameSite: false } // 4 hours
}));

app.use(passport.initialize());
app.use(passport.session());

app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
     res.send(200);
 } else {
     next();
 }
});

I'm also not calling passport.authenticate('login', (err, user, info) => {.. in my wiki app, because again I'm doing this on the main app. Maybe this is preventing deserializeUser from running?

jhowarth15 commented 7 years ago

The issue was that I wasn't sharing the session in a db store between the applications. Deserialize user works when there is a valid session present.

YoshiYo commented 6 years ago

Hey ! Can you explain with an example ?

stevendaye commented 5 years ago

hey @YoshiYo, I think what @jhowarth15 means is that, the deserializeUser would only get called if it finds a session file. So a session must be set correctly in your express-session or session-store configuration while setting the cookie param to false.

I faced the same issue with the deserializeUser(). But mine was getting called at times, but a times not all.

As I was using session-file-store to store session files, there is a little bug in that package causing my deserializeUser not to always find a session file for the cookie to be created. So at time when it finds a session file, deserializeUser is called successfully and logs me in, but at time when I log out to re-login, deserializeUser is not called because of not finding a session file(Like I said, this bug is due to session-file-store).

So make sure the session is set properly in your app.use(session()) and the the cookie is set to false(can be left out as it is by default).

hope it helps your understanding about deserializeUser