【问题标题】:Why are my express sessions not persisting and why am I getting a new session (or multiple sessions) created for each request为什么我的快速会话没有持续存在,为什么我会为每个请求创建一个新会话(或多个会话)
【发布时间】:2019-10-13 01:48:45
【问题描述】:

我有一个使用 express-sessions 的基本 node.js express 应用程序。

请有人帮忙解释为什么会话没有持续存在以及为什么为每个请求创建一个新会话。

应用程序本身非常大,因此我在下面添加了重要设置的简化案例。

const express = require('express');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);

// initialise express
const app = express();
// initialise db session store
const store = new MongoDBStore({
  uri: MONGODB_URI,
  collection: 'sessions',
  // can also set expire here for auto cleanup by mongodb
});

app.use(session({
  secret: 'secret password',
  resave: false,
  saveUninitialized: false,
  httpOnly: false,
  secure: app.get('env') === 'production',
  store,
}));

...routes

在用户登录路由中,应用程序将请求用户设置为会话并保存会话。预计此req,session.user 将在页面之间持续存在,但事实并非如此。在每个页面请求上,我都可以看到正在创建一个新会话(或者有时是多个会话,每个文件请求 1 个)。

【问题讨论】:

    标签: node.js express express-session


    【解决方案1】:

    更新

    TL:DR; - 如果不处理 robots.txt 会导致问题,请将 DEBUG env 设置为 express-session 以进行故障排除

    经过大量拉扯后,我找到了解决方案和一些有用的故障排除技巧。

    在运行您的应用时,将调试设置为 express-session。

    所以对于像我这样的新手来说,使用类似于以下的命令运行您的应用程序:

    DEBUG=express-session node 'bin/www.js'
    

    DEBUG=express-session node app.js
    

    取决于您如何设置应用入口点。

    这样做将打印与会话相关的日志消息,以便您可以排除 cookie 是否实际随每个请求一起发送。错误消息将如下所示:

      express-session fetching 0wgmO1264PsVvqeLqaIIXd6T0ink0zts +34s
      express-session session found +49ms
    

    要解决多个请求导致每个页面加载多个会话的问题,请在应用顶部添加一个中间件,然后再添加任何其他中间件。这将使我们能够查看请求 URL 并排除哪些请求可能会干扰我们的会话。

    // see what requests are being sent and which ones contain cookies
    app.use((req, res, next) => {
      const { url } = req;
      const isCookieSent = req.headers.cookie;
      console.log({ url });
      console.log({ isCookieSent });
      next();
    });
    

    通过这样做我发现罪魁祸首是 robots.txt 文件,显然默认情况下唯一被忽略的路径是 favicon.ico。

    因为这个 robots.txt 路径没有正确处理,也没有发送 cookie,所以导致重复请求,也导致 cookie 不持久。

    要解决此问题,您需要在访问会话中间件之前处理或忽略此请求。

    我使用这个中间件做到了这一点,再次相当高。

    app.get('/robots.txt', (req, res) => {
      res.type('text/plain');
      res.send('User-agent: *\nDisallow: /');
    });
    

    我是 node.js 的新手,所以如果有更多知识的人随时提供额外的信息或更简洁的方法来解决这个问题。希望这可以为你们中的一些人省去很多麻烦!

    【讨论】:

    • 对调试快速会话有很大帮助!这在另一种情况下帮助了我很多。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 2020-07-13
    • 2013-02-23
    • 1970-01-01
    • 2022-11-27
    • 2016-08-07
    • 2011-05-15
    • 2021-05-30
    相关资源
    最近更新 更多