使用 nginx 反向代理的 nodejs restify 无法获得会话工作

nodejs restify with nginx reverse proxy could not get session works

首先介绍一下背景知识:我在我的 nodejs api 服务器上使用了 restify 框架,我在客户端使用 react 与服务器进行交互。我使用 nginx 反向代理将两个项目设置在一个 VPS 中,以处理两个不同的域名:example_server.comexample_client.com 和两个启用了 letsEncrypted 的 https。

所以当我访问 example_server.com 时,我的 nginx 将我带到 localhost:server_port 并显示正确的内容,客户端的工作方式相同。

这是我的问题:

我连接到 restify 服务器的反应客户端无法获得会话工作,服务器无法为客户端设置任何会话。它可能与 nginx 反向代理问题有关,有人使用 express framework for server 有同样的问题,但使用 app.set('trust proxy', 1) 得到修复。但在 restify 中,没有这样的选择。我真的不想将我的代码从 restify 更改为 express,所以我该怎么办?

我的服务器 nginx 设置:

server {
    server_name server_example.com www.server_example.com;
    location / {
        proxy_pass http://127.0.0.1:6000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
}

我的客户端 nginx 设置:

server {
    server_name client_example.com www.client_example.com;
    location / {
        proxy_pass http://127.0.0.1:7000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_redirect off;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
}

我在我的 restify 服务器中使用 express-session 来处理会话,在本地开发中它运行良好,但在带有 nginx 的 VPS 服务器中,它不工作。这是代码片段:

var constant = require('./config/constant.json');
var session = require('express-session');

var restify = require('restify');

var corsMiddleware = require("restify-cors-middleware"); 
const cors = corsMiddleware({  
  origins: constant.client_urls,
  credentials: true,
  allowHeaders: ["Authorization"],
  exposeHeaders: ["Authorization"]
});

var server = restify.createServer();
server.use(restify.plugins.queryParser());
server.use(restify.plugins.jsonp());
server.pre(restify.plugins.pre.userAgentConnection());

server.pre(cors.preflight);  
server.use(cors.actual);


//server.set('trust proxy', 1);  restify didn't has such option, err: .set is not a function.
server.use(session({
  secret: constant.session_secret, 
  proxy: true,
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 3600000, secure: true },
}))

任何帮助将不胜感激!

原来问题是由两个不同的域引起的。

React 客户端 www.myReactClient.com 能够在启用 CORS 的情况下连接到 Restify API 服务器 www.myRestifyServer.com,然后服务器将生成一个会话,在仅发送会话 ID 时将其保留给自己到客户端与 cookie。

React 客户端应携带该 cookie 并在发出请求时将 session-id 发送回服务器,以便服务器识别该客户端。

但是,由于使用了两个不同的域,cookie 被认为是 'third party cookie',浏览器默认阻止这种 cookie,所以 cookie 保留在那里,但从未被使用,所以服务器不会'未收到会话 ID。

所以,长话短说,在我将浏览器设置更改为 NOT 阻止第三方 cookie 后,一切都按计划进行。然后我将我的两个不同的域更改为一个域和一个子域,www.myReactClient.com 用于托管 React 客户端,api.myReactClient.com 用于托管 Restify API 服务器,第三方 cookie 问题也得到解决。