在使用NodeJS和express-session时,使用安全cookie时会话未持久化。

4
我正在使用NodeJS + express + express-session来在应用程序的任何地方持久化用户ID。
在第一个路由上,我的会话被定义。
userProfileRoutes.route('/authentication').post((req, res) => {
  req.session.userID = 10; //example
  console.log(req.session)
}
< p >console.log 的结果是:

Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true,
     secure: true },
  userID: 10 } // this is the right value

但是,从另一个角度来看,我看不到它的价值:
userProfileRoutes.route('/edit').get(function (req, res) {
  console.log('After the nav edit route');
  console.log(req.session);
}

并且这个会打印出

Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true,
     secure: true }
} // ID VARIABLE DISAPEARS HERE

我正在使用以下参数配置express-session

app.use(session({
  secret: 'secret',
  proxy: true,
  resave: false,
  saveUninitialized: true,
  withCredentials: true,
  cookie: { secure: true },
  store: new MongoStore({ mongooseConnection: db })
}));

为什么我的userID在请求之间和所有路由上都没有被保留下来?

你尝试过在app.use中使用cookie: { secure: true, maxAge: 600000 }吗?我猜测会话立即过期,因为没有提及maxAge。 - Sumit Sahay
实际上,我尝试过了,问题不在于会话本身,而是它包含的userID变量。我尝试使用console.log(req.sessionID),它是session对象的一个定义值,但无论何时都不弹出。该会话无处不在,但问题在于其中的userID变量并不是... - user10623427
1个回答

6
您正在设置cookie: { secure: true },但尝试使用HTTP访问服务器。
根据express-session文档cookie.secure 请注意在将其设置为true时要小心,因为符合规范的客户端将不会在未来将cookie发送回服务器,如果浏览器没有HTTPS连接。 请注意,secure:true是一个推荐的选项。 但是,它需要启用https的网站,即对于安全的cookie而言必须具备HTTPS。 如果设置了secure,并且您通过HTTP访问您的站点,则不会设置cookie。
确保您要么使用HTTPS(始终在生产中!)要么将cookie.secure设置为false(仅用于开发!)

Cookies中的secure标志

secure标志是由应用程序服务器在HTTP响应中向用户发送新cookie时可以设置的选项。 secure标志的目的是防止未经授权的第三方观察到cookie,因为cookie在明文传输中传输。
为实现此目标,支持secure标志的浏览器将仅在请求到达HTTPS页面时才发送带有secure标志的cookie。 换句话说,在未加密的HTTP请求上,浏览器将不会发送带有secure标志的cookie。 通过设置secure标志,浏览器将防止通过未加密通道传输cookie。
来自https://www.owasp.org/index.php/SecureFlag

express-session中的cookies

按照常规做法,express-session使用cookie存储会话ID和服务器端存储(在您的情况下是mongoDB)存储会话数据。 如果浏览器无法找到有效的cookie并因此未发送会话ID,则您的服务器将假定没有会话,并在每个请求上将用户ID保存在新会话中。
当您转到/authentication时,它将在新会话中保存ID。 当您尝试在不同的请求中读取时,会话ID已更改,userID中没有值。

好的,现在很多事情都有了解释。就在你发帖之前,我一直在想为什么我的Mongo中存储的sessionID在每个请求后都不同,所以这与我在req.session.idUser中遇到的问题非常相似。我尝试像你说的那样在我的cookie中放置{secure:false},但是在另一个请求之后,sessionID仍然会改变。问题仍然出在“有效cookie”上,不是吗?即使使用{secure:false},浏览器仍然找不到有效的cookie :/ 也许我漏掉了什么,在其他主题中,将{secure:false}放入就足以解决类似的会话问题...谢谢Lucas - user10623427
不确定您所说的用户ID是否会更改,在示例中它将始终为10,您是否设置了随机ID? - lucascaro
ID的更改是会话ID (req.sessionID或req.session.id,由服务器自动分配)。你说得对,我的用户ID在导航过程中不应该更改,因为它是我从数据库中获取的用户ID。但是,我无法在页面之间保持它,因为每次请求后req.sessionID都会更改。 - user10623427
听起来代码里还有其他的 bug。没有看到整个代码很难知道问题出在哪里。现在这已经是个人问题了。你有一个包含错误的 [mcve] 吗? - lucascaro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接