How do I have two Express sessions?

若如初见. 提交于 2019-12-23 04:08:28

问题


I have a Passport-using application with a GraphQL endpoint and a /logout endpoint. For some reason when I called request.isAuthenticated() from inside the GraphQL endpoint I got back true, but when I made the same exact call from inside the /logout endpoint I got back false.

So, I did a bit of logging (of request.session.id) and it turns out that I somehow wound up with two sessions. Stranger still, the session used by my GraphQL endpoint is persistent: if I restart the server it keeps the same ID, while the one in /logout keeps changing.

I think that what's happening is that the persistent session is cookie/DB-based, and so gets restored when my client makes its first request, while the /logout session is not cookie-based and gets reset with the server. What I don't understand is why I have two sessions!

Here's the relevant code:

// Session setup
const store = new KnexSessionStore({ knex, tablename: 'sessions' });
app.use(
  session({
    cookie: { maxAge: 1000 * 60 * 60 * 24 * 5},
    secret: `a secret`,
    store
  })
);

// Passport setup
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));

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

// GraphQL Setup
// NOTE: request.session.id from inside a function in schema = persistent session
const graphQLHandler = graphqlHTTP(request =>({ graphiql: true, schema }));
app.use('/graphql', graphQLHandler);

// Logout Setup
app.get('/logout', (request, response) => {
  // NOTE: request.session.id = non-persistent session
  response.send(`user has been logged out`); // someday do request.logout()
});

As you can see, the express session setup function (session) is only called once. I do call app.use(passport.session()) (which looks like it might be creating a second session), but my understanding is that line just tells Passport to use the session ... it doesn't create a whole separate parallel session.

Can anyone explain what's going on, and how I can get my app to share a single session? Or alternatively if anyone can explain where I could add some code to throw an error whenever a session gets created (so that I can figure out what part of my code creates the second session) that would helpful too.


回答1:


I found the answer! Apparently I wasn't the only one having this problem: https://github.com/jaredhanson/passport/issues/244. You can read all the details there, but ...

TLDR: My client was fetch-ing /logout from the server. However by default fetch doesn't set the { credentials: 'same-origin' } option, and apparently you need to provide that or else Passport just silently starts creating duplicate sessions :(

So it turned out there was nothing wrong with my server code at all, the fix was just doing the following on the client-side:

fetch(`/logout`, { credentials: 'same-origin' });

Here's hoping the Passport people start throwing errors or warnings or something in response to this case, rather than letting their poor users boggle at the inexplicable, but common result (the comment with the answer had 15 thumbs ups).



来源:https://stackoverflow.com/questions/48777201/how-do-i-have-two-express-sessions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!