How to update req.user session object set by passportjs?

前端 未结 5 1286
抹茶落季
抹茶落季 2020-12-17 10:49

I\'m trying to do this since a lot of days but all my tests fails...

Users on my platform connect them by using passportjs strategies (paypal, facebook, google...).<

相关标签:
5条回答
  • 2020-12-17 11:19

    For 'serializeUser' you are returning the entire user... which will serialize the entire object and put it inside the cookie used to track sessions. That serialization only happens one time (when the session is established). When the next request comes in, it always deserializes that exact same user object you stored originally, which doesn't have any updates you made to it. That's why logging out and logging back in works, because it retrieves the edited user from your database (I assume), and recreates the session tracking cookie.

    To confirm this answer, put a breakpoint on 'serializeUser', and notice that it is only hit when you login.

    0 讨论(0)
  • 2020-12-17 11:29

    I got the same problem and finally I found the solution:

    var user = newDataObj;
    req.logIn(user, function(error) {
        if (!error) {
           console.log('succcessfully updated user');
        }
    });
    res.end(); // important to update session
    

    The req.logIn will call serialize function and save a new session to db. res.end() is important. without it the session will not be saved.

    0 讨论(0)
  • 2020-12-17 11:35

    Quan Duong's answer was the most useful to me, but here is a bit more realistic scenario:

    async function foo(req, res) {
      // get some data from somewhere
      const newNickname = req.body.nickname;
    
      // update the user database somehow - e.g. mongodb 
      const users = db.getCollection('users');
      await users.updateOne({
        _id: req.user._id
      }, {
        $set: {
          nickname: newNickname
        }
      });
    
      // create a temporary copy of the user w/ the updated property
      const updatedUser = req.user;
      updatedUser.nickname = newNickname
    
      // persist the change to the session
      req.login(updatedUser, async(error) => {
        if (error) {
          res.json({
            err: 'Sorry, there was an error updating your account.'
          });
          return;
        }
    
        /* 
           maybe you need to call another function from here that uses the updated info before 
           responding to the original request
        */
        try {
          await bar(req.user);
        } catch (error) {
          res.json({
            err: 'Sorry, there was an error updating your account.'
          });
          return;
        }
    
        // done
        res.send(200);
      });
    }

    0 讨论(0)
  • 2020-12-17 11:36

    This works and persists for me:

    req.session.passport.user.nickname = 'mynewnickname'
    

    Are you employing caching on your routes that might need busting before refresh?

    (passport serialize is the same)

    passport.serializeUser(function(user, done) { done(null, user); });
    passport.deserializeUser(function(obj, done) { done(null, obj); });
    
    0 讨论(0)
  • 2020-12-17 11:38

    This is still one of the top results for 'update session passport js', so I thought I'd add what worked for me (the provided answers didn't work for me):

    req.session.passport.user.updatedfield= 'updatedvalue'
    req.session.save(function(err) {console.log(err);}
    

    Without req.session.save() the session data would not update for me. Hope this helps someone.

    0 讨论(0)
提交回复
热议问题