问一个关于Nodejs session过期的问题

问一个关于Nodejs session过期的问题

首先来看看我定义sessin的地方,在server.js中 代码如下:

app.use(session({
  cookie: {maxAge: 60000 * 20}, // 20 minutes
  secret: "test",
  store: new MongoStore({
    db: "user"
  }),
  resave: true,
  saveUninitialized: true,
}));

然后再 请求根目录的时候 设置了一个session:

app.get('/',function(req,res,next){
	req.session.username="admin";
	res.render('main.html'); 
});

我设置了20分钟的过期时间,可是结果不是我想要的。 看看输出日志

[2014-09-15 09:39:29.040] [INFO] dateFileLog - urlcontent_info
[2014-09-15 09:39:29.041] [INFO] dateFileLog - session{"cookie":{"originalMaxAge":1200000,"expires":"2014-09-15T01:59:06.506Z","httpOnly":true,"path":"/"},"username":"admin"}

[2014-09-15 09:41:08.380] [INFO] dateFileLog - urlset
[2014-09-15 09:41:08.380] [INFO] dateFileLog - session{"cookie":{"originalMaxAge":1200000,"expires":"2014-09-15T01:59:29.377Z","httpOnly":true,"path":"/"},"username":"admin"}

[2014-09-15 09:41:37.148] [INFO] dateFileLog - urlcontent_info
[2014-09-15 09:41:37.148] [INFO] dateFileLog - session{"cookie":{"originalMaxAge":1200000,"expires":"2014-09-15T02:01:30.278Z","httpOnly":true,"path":"/"},"username":"admin"}

为什么 expires 对应的时间 在每次请求的时候会改变呢?


4 回复

关于Node.js Session过期的问题

在Node.js应用中,Session的管理是一个常见的需求。你希望设置一个20分钟的Session过期时间,但是发现每次请求时,expires的时间都在变化。这可能是由于Session中间件的一些默认行为导致的。

问题分析

你使用的是express-session中间件,并且通过配置cookie.maxAge来设置Session的过期时间。然而,express-session在处理Session时,会对maxAge进行一些额外的处理,这可能导致你看到的expires时间发生变化。

具体来说,express-session会在每次请求时重新计算Session的expires时间。如果你没有显式地设置resavefalse,那么每次请求都会保存Session,这会导致expires时间被更新。

解决方案

你可以通过以下步骤来确保Session的过期时间保持一致:

  1. 禁用自动保存:将resave设置为false
  2. 明确设置过期时间:确保cookie.maxAgecookie.expires的值是一致的。

以下是修改后的代码示例:

const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);

const app = express();

app.use(session({
  cookie: {
    maxAge: 60000 * 20, // 20 minutes
    expires: new Date(Date.now() + 60000 * 20) // Explicitly set the expiration time
  },
  secret: "test",
  store: new MongoStore({
    db: "user"
  }),
  resave: false, // Disable automatic saving of the session
  saveUninitialized: true,
}));

app.get('/', function(req, res, next) {
  req.session.username = "admin";
  res.render('main.html');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

解释

  • resave: false:禁用自动保存Session,只有在Session发生更改时才保存。
  • cookie.expires:显式设置cookie的过期时间,以确保每次请求时expires时间不变。

通过这些调整,你应该能够使Session的过期时间保持一致。


cookie expire 时间是当前时间+20分钟,resave: true 使每次请求都重写cookie。没有错误吧。

2014-09-15T01:59:06.506Z 要转成当地时间,进行比较。

在你的代码中,maxAge 是设置 session 的过期时间,但是 originalMaxAgeexpires 的变化是因为每次请求时 session 的状态可能被更新,导致 expires 时间重新计算。

具体来说,expires 时间是基于 maxAge 计算出来的,表示 session 何时过期。每次请求时,如果 session 被修改或访问,expires 时间可能会重新计算。这就是为什么你在日志中看到 expires 时间不断变化的原因。

为了验证 session 的过期时间是否按预期工作,你可以通过两次请求之间的间隔来测试。例如:

  1. 首次请求后记录当前时间。
  2. 等待 20 分钟后再发送一次请求。
  3. 检查 session 是否仍然有效。

下面是简化版的示例代码,用于设置和读取 session:

const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);

const app = express();

app.use(session({
  cookie: { maxAge: 60000 * 20 }, // 20分钟
  secret: 'test',
  store: new MongoStore({ db: 'user' }),
  resave: true,
  saveUninitialized: true,
}));

app.get('/', (req, res) => {
  req.session.username = 'admin';
  res.send('Session set.');
});

app.get('/check', (req, res) => {
  if (req.session.username) {
    res.send(`Session is valid. Username: ${req.session.username}`);
  } else {
    res.send('Session expired or not set.');
  }
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

在这个示例中,首次访问 / 会设置 session,并在 /check 路由中检查 session 是否仍然有效。你可以通过两次请求之间等待 20 分钟来测试 session 的过期时间。

回到顶部