【问题标题】:Multiple sessions created for every request in express.js为 express.js 中的每个请求创建多个会话
【发布时间】:2018-11-05 18:13:28
【问题描述】:

我在这里描述的问题发生在我的本地开发机器上,浏览器请求和应用程序之间没有任何代理。 我有几个 Node.js 微服务,它们共享用于管理会话的相同技术:

通常的流程是用户在身份验证应用程序中进行登录,然后被重定向到前端(一个 React 应用程序),该前端向运行 GraphQL 服务器的后端微服务执行 CORS 请求。 这个问题与the one described here 非常相似,即使我的配置略有不同(静态路由仅在身份验证应用程序中并在会话定义之前使用,falseresavesaveUninitialized 选项)。

两个身份验证/后端应用程序都具有以下配置:

const sessionOptions = {
    store: new RedisStore({
        client: redisClient,
        disableTTL: true,
    }),
    secret: "123",
    resave: false,
    saveUninitialized: false,
    proxy: false,
    rolling: true,
    cookie: {
        domain: config.cookie.domain,
        sameSite: config.cookie.sameSite,
        maxAge: toTime(config.cookie.maxAge).ms(),
        secure: config.cookie.secure,
    },
};
app.use(session(sessionOptions));

// Configure passport middleware
app.use(passport.initialize());
app.use(passport.session());

后端应用有额外的 CORS 配置:

app.use(cors({
    origin: "frontend_url",
    credentials: true,
    methods: ['GET', 'POST'],
}));

初始 Redis 状态:

127.0.0.1:6379> KEYS "*"
(empty list or set)

我进入登录页面并创建了一个会话:

127.0.0.1:6379> KEYS "*"
1) "sess:H5VTTBiNSQqu0Fsp2ZfSH2wBZtL4XEZh"

我确实登录了,会话仍然是一个,直到我被重定向到我的 React 应用程序,然后我得到六个新会话:

127.0.0.1:6379> KEYS "*"
1) "sess:NNWse-sp51fVRf6rlnsFpMlZO1gkPgYC"
2) "sess:ofQhH0iBbZOvsJBYMxwHjLL0DKxuFKfS"
3) "sess:XxsTGSoANPE5-fPYbwLmoCgvDho0NTnk"
4) "sess:9wFDQ3_RibJyEXEmJ_8gCxfnak4Uh0yP"
5) "sess:8khC8fgbtO53mJNilMhp88toIcsizxea"
6) "sess:jfQBWogefBr75IgZ5GykSgd5d3t3Mt_D"
7) "sess:H5VTTBiNSQqu0Fsp2ZfSH2wBZtL4XEZh"

无论我点击什么链接,它都会将他们的数量增加到 16,依此类推。我无法发现对我的后端没有发送会话 cookie 而是发送 OPTION 飞行前请求的任何请求。所以我尝试使用my own configuration instead than CORS module,但没有任何改变。 如果我注销,显然只有与我的会话 cookie 匹配的原始会话会从 Redis 中删除,其余的(因为我已禁用 TTL 以拥有“永久”会话)只是悬在那里。 很明显,我不希望 Redis 充满无用的会话,但我找不到真正的问题。 有什么建议吗? 谢谢。

更新:我注意到如果我尝试使用自定义的东西修改 genid 函数时会出现不同的行为:

  • 对于身份验证服务,如果我没有定义 req.body.username (${req.body.username}_${uuidv4()}),我会返回 null
  • 对于后端服务,我每次都返回null

对 auth 服务的第一个请求引发异常 invalid csrf,因为可能无法在 Redis 中找到它,因为 genid 现在返回 null。第二个请求(假设您使用与以前相同的电子邮件并且登录成功)将我带到前端,这一次我只能看到一个正在创建的会话。 显然,这不是一个正确的流程,但奇怪的是它在 Redis 中只创建了一个会话。

【问题讨论】:

    标签: session redis express-session


    【解决方案1】:

    不确定这是否已完全解决,但考虑到您的布局顺序,您可能在会话处理程序之后有 cors 处理程序。由于预检请求进入会话,因此可能会为每个请求创建会话,因为没有发送会话 cookie 或凭据。简单的解决方法是将 cors 处理程序移到会话处理程序上方。

    【讨论】:

      【解决方案2】:

      几天前我遇到了同样的问题!我已经建立了我的仓库并分享了我的链接!它完美无缺!请检查一下。

      https://github.com/ritwbanerjee/angular-node-seed

      【讨论】:

      • 谢谢,但我看不出与我的用例有什么特别不同的地方,所以我不明白为什么我仍然遇到这个问题。
      • 您能否分享指向您的仓库的链接,以便我们查看您的中间件配置
      • 嗨 Ritwik,别担心,最后,我发现了一些在没有传递 cookie 的情况下调用的路由,因此我将它们从会话管理中排除,因为我在那里使用了基于令牌的授权系统。
      【解决方案3】:

      最后,我发现一些发送到我的身份验证服务的请求没有设置会话 cookie,对于某些甚至不应该使用的路径。 所以我定义了那些与会话相关的路径:

      const sessionPaths = ['/path1', '/path2', ...];
      app.use(sessionPaths, session(sessionOptions));
      app.use(sessionPaths, passport.initialize());
      app.use(sessionPaths, passport.session());
      app.use(sessionPaths, csrf());
      

      【讨论】:

        猜你喜欢
        • 2015-07-25
        • 2013-07-26
        • 2016-01-18
        • 2016-08-07
        • 2011-05-15
        • 2012-08-08
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多