Tuesday, August 22, 2017

Modifying user.username in Session With PassportJS

Leave a Comment

I have a form that allows people to update their profile information, which is populated with data from req.user via PassportJS.

The problem is that whenever I update the value that corresponds to user.username I get the following error message:

TypeError: Cannot read property '_id' of null  

From line 6 in this snippet of code:

passport.deserializeUser(function(id, done) {   mongo.connect("mongodb://localhost:27017/formulas", function(e, db){   if (e) {return next(e);}   var col = db.collection("users");   col.findOne({"username": id}, function(err, user){     done(err, {"id": user._id, "username": id, "activeEmail": user.activeEmail, "name": user.name, "password": user.password, "formulas": user.formulas});     });   }); }); 

I'm assuming it's because in serializeUser I'm using user.username to load it into session like so:

passport.serializeUser(function(user, done) {   done(null, user.username); }); 

Does anyone know how to go about getting around this or is it an intractable issue with Passport?

The code I have that does the update generically looks like this:

router.post('/update-profile', function(req, res) {     var name = req.body.name;     var username = req.body.username;     var db = req.db.collection('users');      db.updateOne({"username": username}, {       $set: {           "name": name,           "username": username,         }       }, function(err, r) {          assert.equal(null, err);          assert.equal(null, r.matchedCount);       }     });     res.render('profile', {       user: req.user     });   }); 

UPDATE:

Per comment request, the error message from findOne in serializeUser is null when it's called, so it's not the query that's the problem.

2 Answers

Answers 1

As username is changeable value, you should not use it as session cookie key.

I strongly recommend using user._id instead as it is unchanged value, so that server still "know" the current user even if username has been changed. Check official http://passportjs.org/docs, they are also using id as session cookie key.

Btw, even if you are using username, you should do NULL check for passport.deserializeUser():

col.findOne({"username": id}, function(err, user){     if (user) {         done(err, {"id": user._id, "username": id, "activeEmail": user.activeEmail, "name": user.name, "password": user.password, "formulas": user.formulas});     } else {         done(new Error('User not found'));     } }); 

Answers 2

Please update your code on passport deserialize funtion. You didn't checked, user is available or not. So when no user found, You got that error>

passport.deserializeUser(function(id, done) {   mongo.connect("mongodb://localhost:27017/formulas", function(e, db){   if (e) {return next(e);}   var col = db.collection("users");   col.findOne({"username": id}, function(err, user){     if (err){         done(new Error('No user found on db'));     }else if (user){          done(err, {"id": user._id, "username": id, "activeEmail": user.activeEmail, "name": user.name, "password": user.password, "formulas": user.formulas});     });     }   }); }); 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment