关于快递会话商店的一些奇怪之处

时间:2012-04-22 05:34:45

标签: session node.js express mongoose

如果我在会话中存储对象:

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是未定义的?

1 个答案:

答案 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对象中。