我如何以及何时生成Node/Express cookie密钥?

Max*_*m P 2 cookies session mongodb node.js express

我正在构建一个节点/快速应用程序,并使用express-sessionmongo-connect模块来存储我的会话并在重新启动时保留它们.

但是,每次重新启动服务器时仍会生成新的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
         })
}));
Run Code Online (Sandbox Code Playgroud)

问题在于我的randomString功能 - 当我用静态字符串替换它时,我的会话在服务器重启时仍然存在.我的cookie秘密应该是什么?我应该选择一个长的随机字符串并存储在ENV变量中吗?

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

ski*_*tle 16

典型的会话cookie看起来像这样:

s%3Al3ozSdvQ83TtC5RvJ.CibaQoHtaY0H3QOB1kqR8H2A
Run Code Online (Sandbox Code Playgroud)

它会比这长,但格式大致相同.

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

您可以将其secret视为用于生成签名的密码

通常,签名用于确认文本来自正确的位置.有人可能会篡改文本,但他们无法使用正确的签名对其进行签名,因为他们不知道secret.在cookie的上下文中,cookie的"起源"是服务器本身,因此它只提供了一种方法来确认返回的cookie与发送的cookie相同.

但是,在会话ID的上下文中并不重要,因为如果有人更改了会话cookie,那只会意味着他们将不再登录,因为它与数据库中的id不匹配.那么为什么要打扰他们呢?

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

让我们把它带到一个假设的极端.不要使用随机会话ID,而是让我们只计数,所以第一个会话有id 1,下一个会话就是2等等.有人可以很容易地猜出会话ID是什么,但这还不足以劫持会话.他们还需要能够签名,得到这样的东西:

s%3A432.D5egYRj1G7sJyfbyB7jDh7Gf
Run Code Online (Sandbox Code Playgroud)

这里的会话ID是432并且不难猜测,但是如果不知道签名,黑客就无法对该知识做任何事情.因此,即使您可以猜出"随机"部分,签名也很难猜测cookie值.

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

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

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

差不多.它不一定要疯狂,但确实需要让人猜测.这有点像密码,但有一个优点,你不必记住它.理想情况下,您可以将secret生产中使用的代码保留在代码中,并且使用环境变量将是实现此目的的一种方法.

  • 我想知道有多少开发人员只是复制了那个例子的秘密,哈哈 (9认同)
  • 非常感谢您提供这个令人难以置信的彻底和易懂的答案 - 我已经在谷歌上搜索了几个小时,这是我找到的最好、最相关的解释。谢谢! (5认同)