6

如果我像这样在会话中存储一个对象:

user.name = "Kelvin"; // user is an object pass by "mongoose" findOne's callback.
req.session.user = user; 
console.log(req.session.user.name); // Kelvin

之后,我在其他快递路线中访问“用户”:

app.get("/somepath", function(req, resp) {
    console.log(req.session.user.name); // undefined
});

我想知道为什么 req.session.user.name 除了我设置的函数之外没有定义?

4

1 回答 1

17

在查看了 mongoose 源代码后,我可以说这是因为 mongoose 模型和会话是如何工作的。当您调用req.session.user = userthen时req.session.user指向对象,但实际上数据需要存储在某处(如内存或 Redis)。

为了做到这一点,Express 调用JSON.stringify(sess)和字符串存储在内存中。这是猫鼬进入的地方。模型的构造方式是,当您对它们进行字符串化时,包含 Schema 中预定义的属性。因此,当您设置req.session.user = userExpress 字符串化user(您松散name属性)并保存数据时。当您调用req.session.user另一个路由时,Express 会解析字符串化数据并获得没有name属性的对象。

现在如何解决这个问题?有几种方法。

  • name向 Schema添加属性;
  • 为用户定义新的文字对象:

    var newuser = { id: user.id, name : "Kelvin", pwd: user.pwd, etc. }; req.session.user = newuser;

  • 在另一个字段中存储名称:(req.session.name = "Kelvin";最好的解决方案恕我直言)

顺便说一句:您不应该在会话中持有用户对象。如果像管理员这样的其他用户对用户对象进行了更改怎么办?你根本看不到他们。我建议在会话中只保留用户的 id 并制作自定义中间件以从数据库加载用户并将其存储在request对象中。

于 2012-04-22T09:14:49.663 回答