Reputation: 35797
I've got a problem where one place in my code (the authentication part) puts something in the session, and another place in the code tries to access it (my GraphQL API part). The problem is, when the second part tries to get the data, it isn't there.
When I log request.session.id
I can see the core problem clearly: in between the two requests the session itself changes. The auth request happens, and does put the data in to session A, but when the graphQL code accesses request.session
it gets session B, with no data.
However, this is not a "please debug my code for me" request. Instead, I would just like to understand how the library works, so I can debug myself.
Can anyone please explain how/why express-session
decides (presumably on getting a new request) that it should abandon the old session and start a new one? From what I've read it likely has something to do with my domain settings, but I've tried playing with those without success, and really I just want to understand how the library works, specifically in terms of deciding to re-use a session or generate a new one.
Upvotes: 2
Views: 368
Reputation: 1147
@machineghost what a great question! There is a lot of confusion around what the express-session
module does and how to configure it. I'll do my best to explain.
I think the confusion around express-sesion
originates in the fact that the module is basically just gluing different aspects of a webserver into one place, i.e. req.session
, for middleware, routes, and potentially (with help) websocket connections to store and access ephemeral data about the "user" (read session) who is making the request.
The three aspects that the module tries to glue together are http cookies, a shortish term data store, and the javascript object req
that is passed around through middleware and routes. To shed some light on how this works think about a "normal" HTTP request that has been given to an Express app which is using the express-session
module (ES for short):
connect.id
cookie - ES would have way less issues reported, IMO. NOTE: you can work around the requirement for cookies, but it's hacky at best.req
object called session
that is just an empty object, i.e. {}
. Middleware or routes further down the line will all have access to this.res
object as a way for future requests to have the session attached, as described above.req.session
object. Options like resave and saveUninitialized will determine if ES saves the session for a given request. NOTE: In the case of HTTP redirects, e.g. 302, the res.end
method is not called until after the newly redirected request is made. This means that session data that is set before a redirect is not available to the redirected request. This is a known issue and the workaround is to explicitly save the session before redirecting with req.session.save
In order to get websockets working with ES, at a basic level, you have to take the session that is attached to the request to change protocols and attach it to the socket for that user. I wrote a simple lib as an example here. Note: this is 5 years old and was created more as a talking point than anything, but if you look through how it works you will get the idea.
I hope all of this helps, thanks for posting!
Upvotes: 6