如果我在会话中存储对象:
user.name = "Kelvin"; // user is an object pass by "mongoose" findOne's callback.
req.session.user = user;
console.log(req.session.user.name); // Kelvin
之后,我在其他快递路线中访问“user”:
app.get("/somepath", function(req, resp) {
console.log(req.session.user.name); // undefined
});
我想知道除了我设置的函数之外,为什么req.session.user.name是未定义的?
答案 0 :(得分:16)
在查看mongoose源代码后,我可以说这是因为mongoose模型和会话的工作原理。当你调用req.session.user = user
然后req.session.user
指向对象,但实际上数据需要存储在某个地方(如内存或Redis)。
为了做到快速调用JSON.stringify(sess)
并且字符串存储在内存中。这是猫鼬进入的地方。模型是以这样的方式构造的,当您对它们进行字符串化时,包含在Schema中预定义的仅属性。因此,当您设置req.session.user = user
快速字符串user
(您松散name
属性)并保存数据时。当您在另一条路线中呼叫req.session.user
时,Express会解析字符串化数据并获得没有name
属性的对象。
现在该如何解决这个问题?有几种方法。
name
属性添加到架构; 为用户定义新的文字对象:
var newuser = { id: user.id, name : "Kelvin", pwd: user.pwd, etc. };
req.session.user = newuser;
将名称存储在其他字段中:req.session.name = "Kelvin";
(最佳解决方案imho)
顺便说一下:你不应该在会话中持有用户对象。如果管理员等其他用户对用户对象进行了更改会怎么样?你根本看不到它们。我建议只在会话中保存用户的id,并制作自定义中间件以从DB加载用户并将其存储在request
对象中。