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

Kev*_*vin 5 session mongoose node.js express

如果我在会话中存储一个对象,如下所示:

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

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

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

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

fre*_*ish 16

在研究了猫鼬源代码后,我可以说这是因为mongoose模型和会话的工作原理.当你调用req.session.user = user然后req.session.user指向对象但实际上数据需要存储在某个地方(如内存或Redis).

为了做那个Express调用JSON.stringify(sess)和字符串存储在内存中.这是猫鼬进入的地方.模型以这样的方式构造,当您对它们进行字符串化时,包含在Schema中预定义的属性.因此,当您设置req.session.user = userExpress stringifies 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";最佳解决方案imho)

顺便说一下:你不应该在会话中持有用户对象.如果管理员等其他用户对用户对象进行了更改会怎么样?你根本看不到它们.我建议只在会话中保存用户的id,并制作自定义中间件以从DB加载用户并将其存储在request对象中.