2017-11-03 129 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上搜索幾個小時,這是我找到的最好,最有針對性的解釋。謝謝! –

相關問題