CryingPoo
CryingPoo

Reputation: 23

NodeJS / PassportJS [local] - Is there a way to update req.user automatically?

Good morning,

I am currently studying beginner courses online using NodeJS, Passport, MongoDB (+Mongoose) and implementing sign up, login, changing details etc.

While implementing edit profile page which allows users to change their name, email address and profile picture, I have noticed that my req.user does not get updated while the course I am watching says that Passport should handle it automatically and his video evidently does so.

The changes I enter is successfully reflected in MongoDB, which I can see from typing db.users.find({}) in mongo but my req.user object doesn't get updated so my pages still render the old name, email and profile picture until I logout and log back in.

I have worked around it by manually updating req.user as per the code below but I was wondering why my codes behave differently to the videos I am watching. Any guidance will be very appreciated.

//from the controller
export const postEditProfile = async (req, res) => {
  const {
    body: { name, email },
    file,
  } = req;
  try {
    await User.findByIdAndUpdate(req.user._id, {
      name,
      email,
      avatarUrl: file ? file.path : req.user.avatarUrl,
    });
    console.log(req.user);  //shows old db information
    req.user.name = name;
    req.user.email = email;
    req.user.avatarUrl = file ? file.path : req.user.avatarUrl;
    res.redirect(routes.me);
    console.log(req.user); //shows new db information
  } catch (error) {
    res.render("editProfile", { pageTitle: "Edit Profile" });
  }
};
//serializing and deserialzing
passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((obj, done) => {
  done(null, obj);
});

Thank you!

Upvotes: 2

Views: 568

Answers (1)

jasonandmonte
jasonandmonte

Reputation: 2028

The req.user object is created after done in deserializeUser is called. It's a common practice to have deserializeUser make a database query which will in turn update the req.user if changes are made after the initial login.

Here's an example that uses sequelize. You may need to modify the code to work with your database query system. The general idea though is that deserializeUser is called on each request so by querying the database you maintain up to date data.

passport.deserializeUser((obj, done) => {
  try {
    const { userId } = obj;
    const { dataValues: user } = await User.findOne({ where: { userId } }) || {};
    if (!user) done(null, false); // no user found
    done(null, user);
  } catch (err) {
    done(err);
  });

Upvotes: 1

Related Questions