是什么让Express-Session决定开始新的会话?

时间:2019-05-04 23:42:17

标签: javascript express session express-session

我遇到了一个问题,我的代码中的一个位置(身份验证部分)将某些内容放入会话中,而代码中的另一个位置尝试访问它(我的GraphQL API部分)。问题是,当第二部分尝试获取数据时,它不存在。

登录request.session.id时,我可以清楚地看到核心问题:在两个请求之间,会话本身发生了变化。发生auth请求,并且确实将数据放入会话A,但是当graphQL代码访问request.session时,它将获得会话B,而没有数据。

但是,这不是“请为我调试代码”请求。相反,我只是想了解库的工作原理,因此可以调试自己。

任何人都可以解释express-session如何/为什么决定(大概是在收到新请求时)决定放弃旧会话并开始一个新会话?从我阅读的内容来看,它可能与我的域设置有关,但是我尝试过与那些域名设置没有关系,真的,我只是想了解库的工作原理,特别是在决定重用会话或生成一个新会话。

1 个答案:

答案 0 :(得分:2)

@machineghost真是个好问题! express-session模块的功能以及如何配置方面存在很多困惑。我会尽力解释。

我认为围绕express-sesion的困惑源于以下事实:该模块基本上只是将Web服务器的不同方面粘合到一个位置,即req.session,用于中间件,路由,并且有可能(在帮助下)websocket连接,以存储和访问有关发出请求的“用户”(读取会话)的临时数据。

该模块试图结合在一起的三个方面是http cookie,一个短期数据存储和通过中间件和路由传递的javascript对象req。为了阐明其工作原理,我们考虑了已向使用express-session模块(简称ES)的Express应用程序发出的“正常” HTTP请求:

  • Express将请求传递给ES。
  • ES寻找它先前设置的cookie。这是大多数报告的错误发生的地方。 ES要求您的应征者有权访问Cookie。反向代理,CORS或Fetch API的错误配置都可能阻止ES访问它尝试在HTTP响应中设置的cookie。如果遇到ES错误的每个人都打开了调试器,请在the entry中为ES中间件设置一个断点,并查看connect.id cookie的存在。国际海事组织,ES将减少报告的问题。注意:您可以解决对cookie的要求,但充其量是很棘手的。
  • 如果ES找到一个cookie,它将使用该值在应用程序在store选项中配置的任何内容中查找会话。可以是Redis或MongoDB,或者如果您未指定它仅在节点进程的内存中。
  • 如果ES找不到cookie或查找未返回会话,它将在req对象session上创建一个属性,该属性只是一个空对象,即{}。中间件或线下的路由都可以访问此。
  • ES如上所述,ES在res对象上设置cookie,作为将来请求附加会话的一种方式。
  • ES用一种函数包装req.end方法,该函数将检查是否应保存req.session对象。 resavesaveUninitialized之类的选项将确定ES是否为给定请求保存会话。注意:对于HTTP重定向,例如302,直到发出新的重定向请求之后,res.end方法才被调用。这意味着重定向之前设置的会话数据不可用于重定向的请求。这是一个常识,解决方法是在使用req.session.save重定向之前显式保存会话。

关于网络套接字的说明

为了使Websocket在ES上可以正常使用,您必须采用附加到请求中的会话来更改协议,并将该会话附加到该用户的套接字上。我写了一个简单的lib作为示例here。注意:这已经有5年历史了,创造的话题比任何东西都多,但是如果您仔细研究一下它的工作原理,就会明白这一点。

希望所有这些对您有所帮助,感谢您的发帖!