它是否在客户端存储某些cookie?如果是这样,我该在哪里找到那个cookie?如果需要,我该如何解码它?
基本上,我想要能够查看用户是否已登录,即使用户此时并不在站点上(就像Facebook知道您在其他站点上登录时一样)。但我认为要理解这一点,我首先应该了解会话是如何工作的。
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]并重新创建[signature]应该在计算上是不可行的。如果无需修改[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 Framework!)不同,会话数据保存在服务器上,因此 cookie 更像是会话的占位符而不是实际会话数据的持有者。
根据这里,看起来默认情况下服务器上的会话数据保存在内存中,但可以更改为实现适当 API 的任何存储形式。
因此,如果要在没有特定 req
请求对象的情况下检查事物,就像您所说的那样,您需要访问相同的存储。在第一页的底部,详细介绍了存储需要实现的必需方法,因此如果您熟悉存储 API,则可以执行类似 .getAll()
的操作(如果存在此类内容),并循环浏览会话数据并读取所需的任何值。
除了已经出色的答案外,以下是我创建的两个图表,用于解释Express会话、它们与Cookie的关系和存储:
图表的解释:
每个Cookie都有一个唯一的“味道”(或
sessionId
)。当草莓曲奇饼干被提交给服务器(在HTTP请求中),服务器识别这个味道并从存储器加载相应的数据:Rosie的数据,并将其填充到req.session
中。
sessionId
)。当草莓饼干被提交到服务器(通过 HTTP 请求),服务器会识别这种口味并从存储中加载相应的数据:Rosie 的数据,并填充 req.session
。 - abernier