集群 Nodejs 服务器和 CAS 服务器:CORS 问题

Clustered Nodejs server and CAS server: CORS issue

我有一个基于 Nodejs 的服务器,它使用一个中间件,基本上将用户重定向到 CAS 来管理身份验证。 CAS 服务器以票据响应,最后我的 Nodejs 服务器用 CAS 为用户 object 交易票据并将其存储在 session.

这个过程在没有集群的情况下工作得很好。

今天我想集群化我的 Nodejs 服务器,使用 https://nodejs.org/api/cluster.html(我已经毫无问题地完成了)。

所以不用:

let server = http.createServer(app);
server.listen(PORT, HOST, () => {
  // Keep a track that the server has been launched
  logger.log(`Server running at http://${HOST}:${PORT}/`);
});

一切正常,我现在有:

if(cluster.isMaster) {

// This is the mother process

  // Let's create the threads
  for(let i=0; i < NB_WORKERS; i++) {
    cluster.fork();
  }

  // When a child crash... Restart it
  cluster.on('exit', (worker, code, signal) => {
    logger.log("info", "A child died (PID: %s). It was killed by code or signal %s. Restarting...", worker.process.pid, dode || signal);
    cluster.fork();
  });
} else {
  // This is a child

  // Create the server, based on http
  let server = http.createServer(app);
  server.listen(PORT, HOST, () => {
    // Keep a track that the server has been launched
    logger.log(`Server running at http://${HOST}:${PORT}/`);
  });
}

当我启动服务器时,它实际上按预期在 NB_WORKERS 个线程上启动服务器。但是当我想用我的浏览器访问我的节点服务器提供的应用程序时,我有以下错误:

上面写着如果你看不到:

XMLHttpRequest cannot load https://localhost:8443/cas/login?
service=http://localhost:3000. No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'http://localhost:3000' is 
therefore not allowed access

https://localhost:8443 是我的 CAS 服务器是 运行,http://localhost:3000 是我的节点服务器是 运行。

请注意,如果我将 NB_WORKERS 设置为 1,一切都会恢复正常。

我知道在我的 CAS 服务器配置中设置 'Access-Control-Allow-Origin' header 可能会使一切正常,但我不明白为什么它使用一个线程而不是两个或更多线程。

我错过了什么?

我终于成功了,所以我 post 在这里以防有人遇到类似的问题。

关于节点会话

正如我所说,我的 Nodejs 服务器将数据存储到会话中。在这种情况下,这是一个简单的快速会话,默认值为 MemoryStore,因为我仍在开发中。

集群时,快速会话默认存储不会在线程之间共享。这意味着本应由会话识别的请求有时并非如此,这取决于哪个线程处理了请求。这导致身份验证中间件再次询问 CAS 服务器。

为了让它工作,我不得不为我的会话使用持久存储,例如 Redis。

关于 CORS 问题

我不太确定是什么导致了这个奇怪的问题,但我的想法是:

  • 由于我的 CAS 服务器使用 HTTPS 协议,由于 TSL(你好,证书交换,密钥交换),两台服务器之间进行了一些握手。如果不止一个线程尝试这样做,也许这些被破坏了(一个使 Hello,然后将响应发送到另一个线程 => 这行不通)。

    仍然很奇怪,因为它非常低级,如果不在内部管理,几乎 none 集群节点应用程序可以工作。

  • 为了让前面的握手工作,我想每个线程都必须以某种方式被识别。一种可能的方法是为每个线程分配一个自定义端口:进程仍在端口 3000 上 运行,但每个线程使用一个自定义端口进行通信。

    也许这是导致我出现问题的原因,但我无法准确判断。


因此,我只需要正确管理我的会话存储即可使其正常工作。但是,如果我在 CORS 问题上的某个地方有误,请告诉我。