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

When to use saveUninitialized and resave in express-session

我是 MEAN 堆栈的新手。我阅读了 express-session github doc 但有些选项我不清楚。这些选项是 saveUninitializedresave

任何人都可以用示例解释一下使用saveUninitializedresave的优点是什么,如果我们改变布尔值会有什么影响这些选项中的值。

语法:-

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

让我们假设会话是全局启用的(针对所有请求)。

当客户端发出 HTTP 请求且该请求不包含会话 cookie 时,express-session 将创建一个新会话。创建一个新会话会做一些事情:

  • 生成唯一的会话 ID
  • 将该会话 ID 存储在会话 cookie 中(以便可以识别客户端发出的后续请求)
  • 创建一个空会话对象,如req.session
  • 根据 saveUninitialized 的值,在请求结束时,会话对象将存储在会话存储(通常是某种数据库)中

如果在请求的生命周期内未修改会话对象,则在请求结束时 saveUninitializedfalse,(仍然空,因为未修改)会话对象将不会存储在会话存储中。

这背后的原因是,这将防止在会话存储中存储大量空会话对象。由于没有可存储的有用信息,会话在请求结束时 "forgotten"。

您想什么时候启用它?例如,当您希望能够识别重复访问者时。您将能够识别出这样的访问者,因为他们发送了包含唯一 ID 的会话 cookie。

关于 resave:对于不支持 "touch" 命令的会话存储,可能必须启用此功能。这样做是告诉会话存储一个特定的会话仍然处于活动状态,这是必要的,因为一些存储会在一段时间后删除空闲(未使用的)会话。

如果会话存储驱动程序没有实现 touch 命令,那么您应该启用 resave 这样即使会话在请求期间没有更改,它仍然会在存储中更新(从而将其标记为活动)。

因此,是否需要启用此选项完全取决于您使用的会话存储。

需要注意的一点是,如果您将saveUninitialized设置为false,除非修改会话,否则不会在浏览器上设置会话cookie。这种行为可能是隐含的,但当我第一次阅读 documentation.

时我并不清楚

on saveUninitialized set true 服务器将向浏览器提供会话 cookie 并将其保存在内存中,即使您没有对会话对象进行任何修改。但是当后面的字段设置为false时,只有当你修改session对象时,服务器才会提供session cookie,如果你已经有session cookie就不用担心了!!

resave:这基本上意味着对于服务器的每个请求,它都会重置会话 cookie。即使请求来自同一用户或浏览器,并且会话在请求期间从未被修改。

saveUninitialized:当创建一个空的session对象,没有设置任何属性时,就是未初始化状态。所以,设置saveUninitializedfalse如果不修改session是不会保存的

resavesaveUninitialized 的默认值都是 true,但不推荐使用默认值。所以,根据用例设置合适的值。

我得出一个结论:

1.When 您将 saveUninitialized 设置为 false,如果您创建的会话对象没有被修改,即留空,那么您将看不到 connect.sid 在您的浏览器 cookie 上。这最终会迫使您的商店不存储会话对象,因为它尚未被修改,即未初始化。 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);
})

因此您可以看到 connect.id cookie 被设置在浏览器或 postman cookie 部分。这也意味着如果您有一个商店与您的会话中间件连接,现在您的会话将存储在商店中。

  1. 如果您将 resave 设置为 true,那么对于每个请求,您的会话 cookie 都会被重置。参考:
  1. 未初始化 = false
    这意味着只有在 req.session
  2. 中修改任何 属性 时,您的会话才会存储到您的存储中
  3. 未初始化=真
    这意味着您的会话每次都会存储到您的存储中以供请求。不会依赖req.session.
  4. 的修改
  5. 重新保存=真
    这意味着当对会话执行修改时,它将重新写入 req.session.cookie 对象。
  6. 重新保存=假
    它不会重写 req.session.cookie 对象。最初的 req.session.cookie 保持原样。