使用 nginx 反向代理的 nodejs restify 无法获得会话工作
nodejs restify with nginx reverse proxy could not get session works
首先介绍一下背景知识:我在我的 nodejs api 服务器上使用了 restify 框架,我在客户端使用 react 与服务器进行交互。我使用 nginx 反向代理将两个项目设置在一个 VPS 中,以处理两个不同的域名:example_server.com
、example_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 问题也得到解决。
首先介绍一下背景知识:我在我的 nodejs api 服务器上使用了 restify 框架,我在客户端使用 react 与服务器进行交互。我使用 nginx 反向代理将两个项目设置在一个 VPS 中,以处理两个不同的域名:example_server.com
、example_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 问题也得到解决。