簡體   English   中英

何時在 express-session 中使用 saveUninitialized 和 resave

[英]When to use saveUninitialized and resave in express-session

我是 MEAN 堆棧的新手。 我閱讀了 express-session github 文檔,但有些選項我不清楚。 這些選項是saveUninitializedresave

任何人都可以舉例說明使用saveUninitializedresave的優點是什么,如果我們更改這些選項中的 boolean 值會有什么影響。

句法:-

app.use(session({
  resave: false,
  saveUninitialized: true,
}))

讓我們假設會話是全局啟用的(對於所有請求)。

當客戶端發出 HTTP 請求,並且該請求不包含會話 cookie 時, express-session將創建一個新express-session 創建一個新會話會做一些事情:

  • 生成唯一的會話 ID
  • 將該會話 ID 存儲在會話 cookie 中(以便可以識別客戶端發出的后續請求)
  • 創建一個空會話對象,如req.session
  • 根據saveUninitialized的值,在請求結束時,會話對象將存儲在會話存儲中(通常是某種數據庫)

如果在請求的生命周期內沒有修改會話對象,那么在請求結束時,當saveUninitializedfalse 時,(仍然為空,因為未修改)會話對象將不會存儲在會話存儲中。

這背后的原因是,這將防止在會話存儲中存儲大量空會話對象。 由於沒有任何有用的存儲,會話在請求結束時被“忘記”。

您希望何時啟用此功能? 例如,當您希望能夠識別經常性訪問者時。 您將能夠識別這樣的訪問者,因為他們發送包含唯一 ID 的會話 cookie。

關於resave :這可能必須為不支持“touch”命令的會話存儲啟用。 這樣做是告訴會話存儲特定會話仍處於活動狀態,這是必要的,因為某些存儲將在一段時間后刪除空閑(未使用)會話。

如果會話存儲驅動程序沒有實現 touch 命令,那么您應該啟用resave這樣即使會話在請求期間沒有更改,它仍然在存儲中更新(從而將其標記為活動)。

因此,如果您需要啟用此選項,這完全取決於您使用的會話存儲。

需要注意的一件事是,如果將saveUninitialized設置為false ,除非修改會話,否則不會在瀏覽器上設置會話 cookie。 這種行為可能是隱含的,但當我第一次閱讀文檔時並不清楚。

resave :這基本上意味着對於對服務器的每個請求,它都會重置會話 cookie。 即使請求來自同一用戶或瀏覽器,並且在請求期間從未修改過會話。

saveUninitialized :當創建一個空會話對象並且沒有設置屬性時,它是未初始化狀態。 因此,如果不修改,將saveUninitialized設置為false將不會保存會話。

兩者的默認值resavesaveUninitialized真實的,但使用的是默認已被棄用。 因此,請根據用例設置適當的值。

  1. 未初始化 = 假
    這意味着當 req.session 中的任何屬性被修改時,您的 session 只會存儲到您的存儲中
  2. 未初始化 = 真
    這意味着您的 session 每次都會存儲到您的存儲中以供請求。 不會依賴req.session的修改。
  3. 重新保存=真
    這意味着當對session進行修改時,它會重新寫入req.session.cookie object。
  4. 重新保存=假
    它不會重寫req.session.cookie object。初始req.session.cookie保持原樣。

在 saveUninitialized 設置為 true 服務器上會為瀏覽器提供會話 cookie 並將其保存在其內存中,即使您沒有對會話對象進行任何修改。 但是當后面的字段設置為 false 時,服務器只會在您修改會話對象時提供會話 cookie,如果您已經擁有會話 cookie 那就不用擔心了!!

我得出一個結論:

1.當您將saveUninitialized設置為false ,如果您創建的會話對象沒有被修改,即留空,那么您將無法在瀏覽器 cookie 上看到 connect.sid。 這最終會強制您的商店不存儲會話對象,因為它尚未被修改,即未初始化。 反之亦然true

例如:

const express = require('express');
const dotenv = require("dotenv").config();
const app = express();
const session = require("express-session");
app.use(session({
  secret:"cat",
  resave:false,
  saveUninitialized:false,
  cookie:{httpOnly:true}
}));
app.get('/login',(req,res)=>{
  // req.session.user="sundar";
  // req.session.admin=true;
  console.log(req.sessionID);
  res.send(req.session.user);
})

app.post("/upload",(req,res)=>{
  console.log(req.session);
  if (req.session.user === "sundar") {
    res.send("uploaded" + req.session.user)
  }else{
    res.send("failed");
  }
  
})

app.listen(process.env.PORT, () => {
  console.log(`Listening on http://localhost:${process.env.PORT}`);
});

在本例中,如果您從郵遞員或瀏覽器點擊/login並且查看 cookie,您將看不到 connect.id,因為創建的會話對象沒有被修改。

但是如果你修改/login為:

app.get('/login',(req,res)=>{
   req.session.user="sundar";
   req.session.admin=true;
/* here we modified session object by adding user and admin properties to object created */
  res.send(req.session.user);
})

因此,您可以看到在瀏覽器或郵遞員 cookie 部分設置了 connect.id cookie。 這也意味着如果您有一個商店與您的會話中間件相連,現在您的會話將存儲在商店中。

  1. 如果您將resave設置為true ,那么對於每個請求,您的 session-cookie 將每次都被重置。 參考: 點擊這里閱讀

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM