Express.js / Passport.js: Where is req.user stored?

15,621

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.

Share:
15,621

Related videos on Youtube

tukkaj
Author by

tukkaj

Updated on June 21, 2022

Comments

  • tukkaj
    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
    tukkaj over 10 years
    As 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
    BML91 about 6 years
    I 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
    user1063287 about 6 years
    I am looking for documentation on req.user and it is not listed as a method of the Request object in the express documentation, I see this answer says it is a "convenience property" for req.session.user, but I can't see req.session in the documentation either. Does anyone know where I can find information about it?
  • GavinBelson
    GavinBelson almost 3 years
    Great answer, it really clears up why deserializeUser() is needed