express req.session 对象是如何持久化的?

Posted

技术标签:

【中文标题】express req.session 对象是如何持久化的?【英文标题】:How is the express req.session object persisted? 【发布时间】:2015-05-01 15:04:39 【问题描述】:

我对学习 Node 和 Express 非常陌生,我仍在尝试用 express 来理解代码流。假设我们在 session.js 中有如下代码:

app.post('/session', notLoggedIn, function(req, res) 
    User.findOne(
        username: req.body.username, 
        password: req.body.password
    , function (err, user) 
        if (err) 
            return next(err);
        
        if (user) 
            req.session.user = user;
            res.redirect('/users');
         else 
            res.redirect('/session/new');
        
    ); 
);

假设 User 是必需的 mongo 模式。我觉得奇怪的是 session.user 分配:

req.session.user = user;

由于 req 变量在重定向后将超出范围,但我们显然这样做是为了保留用户数据,所以我要弄清楚以下哪些场景描述了正在发生的事情。 (A) 分配给 req 参数的参数(当回调被调用时)被存储/仍在堆栈上的某个地方,(B) 会话被存储/在堆栈上并在它之前被分配给一个新的 req 对象传递给回调,或 (C) 与 B 相同,但在用户字段上(似乎不太可能并且可能是我做作的)。

【问题讨论】:

我会看一下代码,它并不多,而且似乎有据可查github.com/expressjs/session/tree/master/session 【参考方案1】:

有一个整体的会话数据结构,用于存储所有用户的所有会话信息(就像一个全局的,但它也可以在一个数据库中 - 至少在连接之间是持久的)。每个客户端的会话数据使用一个唯一键索引到会话存储中以获取该客户端的会话数据。

为给定浏览器客户端建立会话的一部分是创建一个唯一的客户端密钥(通常存储在 cookie 中),该密钥成为全局会话对象的索引。

在传入的 http 请求中,支持会话的 Express 中间件会检查特定的客户端 cookie,如果在 http 请求中找到该特定 cookie 并在全局会话对象/数据库中找到该特定 cookie,则它将该会话的存储信息添加到http 请求处理程序的请求对象以供以后使用。

所以,这是一个典型的序列:

    传入的 HTTP 请求。 中间件检查会话 cookie。 如果会话 cookie 不存在,则创建一个,并在此过程中创建一个唯一 id 来标识此 http 客户端。 在持久会话存储中,为这个新客户端初始化会话。 如果存在会话 cookie,则在会话存储中查找此客户端的会话数据并将该数据添加到请求对象。 会话中间件处理结束 稍后在此 http 请求的 Express 处理中,它会到达一个匹配的请求处理程序。此特定 http 客户端的会话存储中的会话数据已附加到请求对象,可供请求处理程序使用。

【讨论】:

我们可以聊聊吗,我没有什么疑问,一点点帮助对我来说将是一个巨大的好处。 @SurajJain - 这不是这个网站的运作方式。如果您对它的工作原理有任何疑问,您可以自己发布一个新问题,其中包含有关您在理解方面需要帮助的具体细节。 我以前也是这样做的,人家只投反对票,所以我现在在聊天中提问,聊天完全明白,然后在本站回答问题,传播知识。 @jpaddison3 - 是的,通常是这样。 @jpaddison3 - 当您想使用当前数据更新会话存储时,您可以自己调用 req.session.save()在会话中更改。 Express-session 挂钩res.end() 以查看请求何时完成,然后在需要时更新会话存储。【参考方案2】:

我认为接受的答案遗漏了一个关键细节,这是由@jpaddison3 提出的:“Express-session 挂钩 res.end() 以查看请求何时完成,然后在需要时更新会话存储。”

基本上,当您添加表达式会话中间件时,它会包装 res.end() 以便在流关闭之前保存新的会话信息。

【讨论】:

以上是关于express req.session 对象是如何持久化的?的主要内容,如果未能解决你的问题,请参考以下文章

从另一个端点检索时,使用 express-session 保存到 req.session 的数据为空

如何在节点 js 中清除浏览器 cookie 时清除 req.session?

如何从 socket.io 中访问 req.session 变量?

Express.js:app.locals vs res.locals vs req.session

req.session 未定义和 req.session.user_id 不工作

快速会话中的 req.session 不持久