100

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

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

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

4

4 回答 4

175

概述

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

细节

Express.js/Connect 使用创建一个 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)之后cookieParser和中包含路由器 ( )。session

以下是 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。

于 2012-07-20T19:31:55.047 回答
46

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

  • cookie 存储在客户端上,带有一个密钥(服务器将使用它来检索会话数据)和一个哈希值(服务器将使用它来确保 cookie 数据没有被篡改,所以如果你尝试更改cookie 将无效的值)

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

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

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

于 2011-04-02T09:19:31.963 回答
9

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

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

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

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

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

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

于 2011-04-02T09:29:52.943 回答
4

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

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

图表说明:

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

于 2019-12-31T07:54:18.040 回答