If I store an object in session like this:
user.name = "Kelvin"; // user is an object pass by "mongoose" findOne's callback.
req.session.user = user;
console.log(req.session.user.name); // Kelvin
and after that, I access “user” in other routes of express:
app.get("/somepath", function(req, resp) {
console.log(req.session.user.name); // undefined
});
I want to know why req.session.user.name is undefined besides the function I set it?
After looking into mongoose source code I can say that this is because how mongoose models and session works. When you call
req.session.user = userthenreq.session.userpoints to the object but actually the data needs to be stored somewhere (like memory or Redis).In order to do that Express calls
JSON.stringify(sess)and string is stored in memory. Here’s where mongoose enters. Models are constructed in such a way, that when you stringify them only attributes predefined in Schema are included. So when you setreq.session.user = userExpress stringifiesuser(you loosenameattribute) and saves the data. When you callreq.session.userin another route Express parses stringified data and you obtain object withoutnameattribute.Now how to fix this? There are several ways.
nameattribute to the Schema;Define new literal object for user:
var newuser = { id: user.id, name : "Kelvin", pwd: user.pwd, etc. };req.session.user = newuser;Store name in another field:
req.session.name = "Kelvin";(the best solution imho)By the way: You shouldn’t hold the user object in session. What if some other user like administrator makes changes to the user object? You won’t see them at all. I advice holding only the id of the user in session and make custom middleware to load user from DB and store it in
requestobject.