Express.js / Passport.js: Where is req.user stored?
req.user
is a convenience property that is an alias for req.session.user
, which is stored in redis. So for session-enabled requests, the session data is loaded from redis, then req.user
is set to be the same as req.session.user
for convenience, then your code runs and responds to the request, and the in-memory versions of these are eligible for garbage collection once the response is sent. The copies in redis survive until the session expires.
If so, would it be a solution to dump the raw user data into the Mongo database in serializeUser() and then get it from there in deserializeUser()?
Yes, that's the general pattern if you want to use the user data as part of your application data (which is typical). So in the end mongo will have every user who has ever logged in, and redis will have every user with a currently-active session, and memory will have every user the app is in the middle of handling a request from at this instant.
Related videos on Youtube
tukkaj
Updated on June 21, 2022Comments
-
tukkaj almost 2 years
I am developing a web application that is going to be deployed to Heroku.
I have chosen to go with a Node.js stack as I am fed up with "traditional" web frameworks. I am designing the app on Express.js. I've found it very productive and intuitive compared to e.g. Django or Grails.
So the web app is going to have features for both guests and authenticated users. And as the app is deployed to Heroku, which is a cloud platform service, the application cannot have any internal state stored inside the server because of Heroku's load balancers and practices in general. And the fact is that having internal state is also bad design in a distributed environment.
My local development setup has a Redis instance (for storing sessions) and a MongoDB instance (for storing user data, e.g. Facebook user details). I am using Passport.js and passport-facebook to handle authentications. Currently, I have only Facebook authentication implemented which works fine at least locally.
The problem is that I am not sure nor have I read anywhere about how Express / Passport magically populates the req.user object. I'm a bit suspicious about that and it feels like that is stored in server's memory.
passport.serializeUser(function(user, done) { console.log( "This outputs a complete" + "User Profile object when the user logs in.", user); done(null, user); }); passport.deserializeUser(function(obj, done) { console.log( "And this too, but I'm afraid that" + "obj comes from memory.", obj); done(null, obj); });
Passport.js documentation does not tell very well about this one. My guess is that serializeUser() gets the user from Facebook, but deserializeUser() takes it from memory?
If so, would it be a solution to dump the raw user data into the Mongo database in serializeUser() and then get it from there in deserializeUser()?
-
tukkaj over 10 yearsAs a Redis noobie, I've been querying KEYS * in redis-cli, but didn't ever do a GET command to actually access the key contents. Now I see that Redis stores the same JSON as what the deserializeUser() gets. Thanks for your reply.
-
BML91 about 6 yearsI know this comment was made about 3 years ago, but as a similar Redis noob I just made the exact same mistake and this helped me immensely, thanks.
-
user1063287 about 6 yearsI am looking for documentation on
req.user
and it is not listed as a method of theRequest
object in the express documentation, I see this answer says it is a "convenience property" forreq.session.user
, but I can't seereq.session
in the documentation either. Does anyone know where I can find information about it? -
GavinBelson almost 3 yearsGreat answer, it really clears up why
deserializeUser()
is needed