会话如何在 Express.js 和 Node.js 中工作?

IT技术 javascript node.js session cookies express
2021-02-14 22:38:49

使用Express.js,会话非常简单。我很好奇它们实际上是如何工作的。

它是否在客户端存储了一些 cookie?如果是这样,我在哪里可以找到那个 cookie?如果需要,我该如何解码?

我基本上希望能够查看用户是否已登录,即使该用户当时实际上并未在该网站上(就像 Facebook 如何知道您在其他网站上已登录)。但我想明白我应该首先了解会话是如何工作的。

4个回答

概述

Express.js 使用 cookie 在用户的浏览器中存储会话 ID(带有加密签名),然后在后续请求中使用该 cookie 的值来检索存储在服务器上的会话信息。该服务器端存储可以是内存存储(默认)或任何其他实现所需方法的存储(如connect-redis)。

细节

Express.js/Connect使用.js 创建一个 24 个字符的Base64字符串utils.uid(24)并将其存储在req.sessionID. 然后将此字符串用作 cookie 中的值。

客户端

签名 cookie 始终用于会话,因此 cookie 值将具有以下格式。

[sid].[signature]

其中 [sid] 是 sessionID,而 [signature] 是通过使用初始化会话中间件时提供的密钥对 [sid] 进行签名来生成的。签名步骤是为了防止篡改。在不知道所使用的密钥的情况下修改 [sid] 然后重新创建 [签名] 在计算上应该是不可行的。如果不需要修改 [sid],会话 cookie 仍然容易被盗和重用。

这个cookie的名字是

connect.sid

服务器端

如果处理程序出现在cookieParsersession中间件之后,它将可以访问变量req.cookies这包含一个 JSON 对象,其键是 cookie 键,值是 cookie 值。这将包含一个名为的密钥connect.sid,其值将是签名的会话标识符。

这是一个如何设置路由的示例,该路由将检查每个请求上是否存在会话 cookie 并将其值打印到控制台。

app.get("/*", function(req, res, next) {

    if(typeof req.cookies['connect.sid'] !== 'undefined') {
        console.log(req.cookies['connect.sid']);
    }

    next(); // Call the next middleware
});

您还需要确保在配置部分app.use(app.router)之后cookieParsersession包含路由器 ( )

以下是 Express.js/Connect 内部存储的数据示例。

{
  "lastAccess": 1343846924959,
  "cookie": {
    "originalMaxAge": 172800000,
    "expires": "2012-08-03T18:48:45.144Z",
    "httpOnly": true,
    "path": "/"
  },
  "user": { 
    "name":"waylon",
    "status":"pro"
  }
}

user字段是自定义的。其他一切都是会话管理的一部分。

该示例来自 Express 2.5。

@WebHrushi 我在考虑中间人攻击:en.wikipedia.org/wiki/Man-in-the-middle_attack
2021-04-18 22:38:49
当使用 console.log 打印 cookie 值时,它会提供编码(签名)cookie。我如何获得真实信息?
2021-04-29 22:38:49
我如何为任何特定的 session_id 创建令牌?
2021-05-04 22:38:49
有人可以帮我解决这个问题吗:stackoverflow.com/questions/21982791/...
2021-05-06 22:38:49
你是什​​么意思——“如果不需要修改 [sid],会话 cookie 仍然容易被盗和重用。”?由于 SID 是由 express 生成的,我们永远无法更改它,对吗?
2021-05-09 22:38:49

我从未使用过 Express.js,但根据他们关于该主题的文档,它听起来像:

  • Cookie 存储在客户端上,带有一个密钥(服务器将使用它来检索会话数据)和一个散列(服务器将使用它来确保 cookie 数据未被篡改,因此如果您尝试更改cookie 将无效的值)

  • 与某些框架(例如Play 框架!)相反,会话数据保存在服务器上,因此 cookie 更像是会话的占位符,而不是实际会话数据的持有者。

  • 这里看来,服务器上的这个会话数据默认保存在内存中,尽管可以将其更改为实现适当 API 的任何存储形式。

因此,如果您想在没有特定req请求对象的情况下检查事物,就像您说的那样,您只需要访问相同的存储。在第一个文档页面的底部,它详细说明了存储需要实现的所需方法,所以如果你熟悉你的存储 API,也许你可以执行一个.getAll()if 类似的东西存在,并遍历会话数据并读取任何内容你想要的value观。

我很好奇它们实际上是如何工作的。

试着看看这个答案和维基的东西。

它是否在客户端存储了一些 cookie?

是的,它通常是一个带有指定会话 ID 的 cookie,应该用一个秘密签名以防止伪造。

如果是这样,我在哪里可以找到那个 cookie?如果需要,我该如何解码?

您不应该在客户端弄乱会话 cookie。如果你想在服务器端使用会话,你应该查看相关的express.js连接文档。

除了已经很好的答案之外,我还创建了 2 个图表来解释 Express 会话,它们与 cookie 和 store 的链接:

  • 巧克力曲奇: 巧克力
  • 草莓饼干: 草莓

图解说明:

每个 cookie 都有独特的“风味”(或sessionId)。当草莓 cookie 呈现给服务器时(在 HTTP 请求中),服务器识别出这种风味并从存储中加载相应的数据:Rosie 的数据,并填充req.session

@RafaelSofi-zada 每个饼干都有独特的“风味”(或sessionId)。当草莓 cookie 呈现给服务器时(通过 HTTP 请求),服务器识别出这种风味并从存储中加载相应的数据:Rosie 的数据,并填充req.session!
2021-04-20 22:38:49
对不起,我没有从图中得到任何信息。你想用它/在里面传达什么?
2021-05-12 22:38:49