2017-11-03 236 views
0

我正在构建一个节点/快速应用程序,并使用express-sessionmongo-connect模块来存储我的会话并在重新启动时保留它们。如何以及何时生成节点/ Express cookie秘密?

但是,每次重新启动服务器时都会生成新的Cookie ID。我已经收窄的问题记在我的会话密钥,这是16个字符这里随机生成的字符串是我的会话代码:

app.use(session({         
    secret: dbops.randomString(16), // generate a 16 random char string 
     saveUninitialized: false, 
     resave: true, 
     store: new MongoStore({ 
      db: thisDb, 
      ttl: 14 * 24 * 60 * 60 
     }) 
})); 

的问题是我randomString功能 - 当我用一个静态的字符串替换,我的会话通过服务器重新启动持续存在。我的饼干秘密应该是什么?我应该选择一个长随机字符串并存储在一个ENV变量中?

我想我通常仍然对字符串的目的感到困惑,因为我的Cookie SID似乎是随机产生的。

回答

1

一个典型的会话cookie看起来是这样的:

s%3Al3ozSdvQ83TtC5RvJ.CibaQoHtaY0H3QOB1kqR8H2A 

这将是比这更长,但格式是一样的。

  • s%3A在开始时表示它是一个签名cookie。
  • l3ozSdvQ83TtC5RvJ是会话ID(您可以通过检查服务器上的req.session.id来确认这一点)。
  • CibaQoHtaY0H3QOB1kqR8H2A是签名。

你可以认为secret作为一个有点像用于生成签名

一般而言,密码,签名是用于确认文本源于正确的地方。有人可能会篡改文本,但他们将无法使用正确的签名签名,因为他们不知道secret。在cookie的上下文中,cookie的“来源”是服务器本身,因此它只是提供一种方法来确认返回的cookie与发送的cookie是相同的。

但是,在会话id的上下文中并不重要,因为如果有人更改其会话cookie,这意味着它们不会再被登录,因为它不会匹配数据库中的id。那么为什么要麻烦签名呢?

生成随机会话ID实际上是相当困难的。即使它看起来随机,你仍然可能有人猜测它。签名可以帮助解决这个问题:当“随机”ID不是非常随机时,我们如何阻止某人猜测另一个用户的会话ID?

让我们假设这是一个假设的极端。而不是使用随机会话标识,让我们只是数了起来,所以第一次会议编号为1,下一次会话将是2等等。有人很容易猜出会话ID是什么,但这不足以劫持会话。他们还就需要能够签署,让这样的事情:

s%3A432.D5egYRj1G7sJyfbyB7jDh7Gf 

这里的会话ID 432,不会是难以猜测,但不知道签名黑客不能做任何知识。因此,即使您可以猜测“随机”部分,签名也很难猜测cookie值。

返回到有关express-session的问题,顾名思义,secret需要保密。它需要在重新启动之间保持不变,或者正如您所注意到的,签名全部变为无效,而旧的会话Cookie将全部被拒绝。它也需要在群集中的节点之间相同,因为不能保证请求将始终转到同一个节点。

您还应该注意可以使用的keys设置,而不是secret。使用keys可让您更改用于生成签名的secret,而不会立即使所有现有会话无效。这个想法是你指定了一个密钥数组(秘密)。只有第一个用于生成签名,但所有条目对于检查cookie上的传入签名是有效的。这个想法很简单,只要需要,旧的秘密就可以包含在数组中,然后一旦我们确信没有会话正在使用它们,就可以将其删除。

我应该选择一个长随机字符串并将其存储在ENV变量中吗?

非常多。它不一定非常疯狂,但对于某人猜测确实很困难。这有点像密码,但有一个好处,你不必记住它。理想情况下,您可以将代码中使用的secret保留下来,并且使用环境变量是实现该目的的一种方法。

+0

对于这个令人难以置信的彻底和易于理解的答案,我还不够感谢 - 我一直在Google上搜索几个小时,这是我找到的最好,最有针对性的解释。谢谢! –

相关问题