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 = user
then req.session.user
points 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 set req.session.user = user
Express stringifies user
(you loose name
attribute) and saves the data. When you call req.session.user
in another route Express parses stringified data and you obtain object without name
attribute.
Now how to fix this? There are several ways.
name
attribute 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 request
object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With