使用Express.js,会话非常简单。我很好奇它们实际上是如何工作的。
它是否在客户端存储了一些 cookie?如果是这样,我在哪里可以找到那个 cookie?如果需要,我该如何解码?
我基本上希望能够查看用户是否已登录,即使该用户当时实际上并未在该网站上(就像 Facebook 如何知道您在其他网站上已登录)。但我想明白我应该首先了解会话是如何工作的。
使用Express.js,会话非常简单。我很好奇它们实际上是如何工作的。
它是否在客户端存储了一些 cookie?如果是这样,我在哪里可以找到那个 cookie?如果需要,我该如何解码?
我基本上希望能够查看用户是否已登录,即使该用户当时实际上并未在该网站上(就像 Facebook 如何知道您在其他网站上已登录)。但我想明白我应该首先了解会话是如何工作的。
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
如果处理程序出现在cookieParser
和session
中间件之后,它将可以访问变量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。
我从未使用过 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
。