在带有 express-session 的 NodeJS 中使用安全 cookie 时会话不持久

Posted

技术标签:

【中文标题】在带有 express-session 的 NodeJS 中使用安全 cookie 时会话不持久【英文标题】:session not persisting when using secure cookie in NodeJS with express-session 【发布时间】:2019-04-12 22:11:33 【问题描述】:

我正在使用 NodeJS + express + express-session 从应用程序的任何位置保存用户 ID。

在第一条路线上,我的会话已定义

userProfileRoutes.route('/authentication').post((req, res) => 
  req.session.userID = 10; //example
  console.log(req.session)

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 )
));

为什么我的用户 ID 在请求之间和所有路由上都没有保留?

【问题讨论】:

你在app.use 中尝试过cookie: secure: true, maxAge: 600000 , 我猜会话会立即过期,因为没有提到maxAge。 确实我试过了,问题不在于会话本身,而在于它包含的变量 userID。我试图 console.log(req.sessionID) 这是对象会话的定义值,它会在任何地方弹出。会话无处不在,但问题是其中的变量 userID 不是... 【参考方案1】:

您正在设置cookie: secure: true,但尝试使用 HTTP 访问您的服务器。

来自express-session documentation:

cookie.secure

请注意,将此设置为 true 时要小心,因为如果浏览器没有 HTTPS 连接,兼容的客户端将来不会将 cookie 发送回服务器。

请注意,secure: true 是推荐的选项。但是,它需要启用 https 的网站,即安全 cookie 需要 HTTPS。如果设置了安全,并且您通过 HTTP 访问您的站点,则不会设置 cookie。

确保您使用 HTTPS(始终在生产中!)或将 cookie.secure 设置为 false(也许,并且仅用于开发!)

cookies 中的安全标志

安全标志是应用服务器在 HTTP 响应中向用户发送新 cookie 时可以设置的选项。安全标志的目的是防止由于 cookie 以明文形式传输而被未授权方观察到。

为实现此目标,支持安全标志的浏览器将仅在请求转到 HTTPS 页面时发送带有安全标志的 cookie。换句话说,浏览器不会在未加密的 HTTP 请求上发送设置了安全标志的 cookie。 通过设置安全标志,浏览器将阻止通过未加密通道传输 cookie。

来自https://www.owasp.org/index.php/SecureFlag

快速会话中的 Cookies

按照惯例,express-session 使用 cookie 来存储 会话 ID 并使用服务器端存储(在您的情况下为 mongoDB)来存储 会话数据。如果浏览器因为找不到有效的 cookie 而没有发送您的会话 ID,您的服务器将假定没有会话,并在每次请求时将用户 ID 保存在新会话中。

当您到达/authentication 时,它会将 ID 保存在新会话中。当您尝试在不同的请求中读入时,会话 ID 已更改并且您在 userID 中没有任何值。

【讨论】:

好吧,这说明了很多事情。就在您发布之前,我想知道为什么我存储在 Mongo 中的 sessionID 在每次请求后都不同,所以它与 req.session.idUser 的问题完全相同。如您所说,我尝试将 secure: false 放入我的 cookie 中,但 sessionID 在另一个请求后仍在更改。问题仍然在于“有效的cookie”不是吗?即使使用 secure:false,浏览器也找不到有效的 cookie:/ 也许我遗漏了一些东西,在其他主题上放置 secure:false 足以解决会话的类似问题......谢谢卢卡斯 不确定用户 id 改变是什么意思,在示例中它始终为 10,您是否设置了随机 id? ID改变的是会话一(req.sessionID或req.session.id,由服务器自动分配)。你是对的,我的用户 ID 不应该改变导航,因为它是我从数据库中为用户获取的 ID。但我无法通过页面保留它,因为 req.sessionID 在请求后总是在变化 听起来代码中还有其他错误。没有看到整个事情很难知道。现在这是个人的。您是否有发生错误的minimal reproducible example?

以上是关于在带有 express-session 的 NodeJS 中使用安全 cookie 时会话不持久的主要内容,如果未能解决你的问题,请参考以下文章

express中的会话存储方式

Express-Session 在生产/部署中不起作用

使用 express-session 和 JWT

node.js中express-session配置项详解

express中使用express-session记录登陆状态

nodejs-5.7 express-session