【问题标题】:express.js sessions with reverse proxy带有反向代理的 express.js 会话
【发布时间】:2012-09-06 08:28:09
【问题描述】:

我已经设置了一个 Apache 反向代理来将 api.mydomain.com 转发到 localhost:2000,它工作得很好。

但是,我遇到的真正问题是关于会话 - 通过api.mydomain.com 查询时似乎没有存储 req.session。来自localhost:2000 的会话可以正常访问。

我认为这与代理域有关...

server.js

var express = require('express'),
    app = express();

app.enable('trust proxy');

app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'supersecret'});
    app.use(app.router);
});

app.get('/session', function(req, res, next){ 
    console.log(req.session.username)
    // this will be undefined when called from  api.mydomain.com...
});


app.post('/session', function(req, res, next){ 
    req.session.username = 'my username';
});

apache 配置

<VirtualHost *:80>
    ServerName api.mydomain.com   
    ProxyPass / http://localhost:2000/
    ProxyPassReverse / http://localhost:2000/

    ProxyPreserveHost On
    ProxyPassReverseCookieDomain api.domain.com localhost:2000
    ProxyPassReverseCookiePath / /
</VirtualHost>

编辑

值得注意的是,为了进一步测试 - 在 app.use(app.router) 之前添加以下代码 app.configure() ....

app.use(function (req, res) {
    res.send('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
});

将导致以下结果(每行代表对应用程序的新 GET /session 请求 - 节点也没有重新启动)。

本地主机:2000

Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq
Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq
Hello, your session id is sHkkESxJgzOyDhDwyTjwpNzq

api.mydomain.com

Hello, your session id is uuo4U5ierZAG8LSH1BdwTlVf
Hello, your session id is 8BxL97Bo35SDt4uliuPgnbia
Hello, your session id is 0xkqZZpzQNvTsQpbJtUlXgkR

设置信息

NodeJS v0.8.8

Apache v2.4.2

ExpressJS v3.0.0rc4

更新 2

嗯,到目前为止,我已经决定简单地使用mydomain.com/api,因为这似乎可以解决所有问题。所以我想这只是与 Apache 如何使用 Express 处理域通信有关!

【问题讨论】:

  • 值得注意的是,我在这里使用配置尝试了与 nginx 完全相同的事情 - blog.argteam.com/coding/… 但没有 ssl 并产生了与上述相同的问题。 SSL 是会话的要求吗?
  • 我在尝试复制您的问题时遇到了类似的问题 - 直到我清除了浏览器 cookie。清除 cookie 后,您能否验证问题是否仍然存在?您使用什么浏览器/HTTP 客户端来处理请求?
  • @zzen,使用 Chrome 和 Firefox。每当这些事情发生时,我都会确保清除我的缓存,但似乎没有帮助。值得注意的是,当在目录而不是子域(例如 domain.com/api 而不是 api.domain.com)上运行时,我有反向代理工作,这让我认为这完全是域处理的问题表达..
  • 你还能添加关于node、express和apache版本的信息吗?我已经复制了你的代码和 apache 配置,并且一切正常(在清除我的 cookie 之后)。
  • @zzen 这很奇怪 - 更新了。

标签: apache node.js session proxy express


【解决方案1】:

将以下内容添加到 server.js

app.enable('trust proxy');

引自 ExpressJS API 文档:http://expressjs.com/api.html#app-settings ...

trust proxy - 启用反向代理支持,默认禁用

【讨论】:

  • 好主意,我确实遇到过这个。但是,它似乎不起作用。我什至根据 connect.js 文档将proxy: true 添加到app.use(express.session(); ...
【解决方案2】:

根据Apache ProxyPass and Sessions 判断,这个 apache 配置也许 ...

<VirtualHost *:80>
    ServerName api.mydomain.com   
    ProxyPass / http://localhost:2000/
    ProxyPassReverse / http://localhost:2000/
    ProxyPassReverseCookiePath / /
</VirtualHost>

【讨论】:

  • 另一个很可能会奏效的好主意,但还是不行!我还尝试了各种其他选项ProxyDomain api.mydomain.comProxyPreserveHost OnProxyRequests OnProxyVia OnProxyPassReverseCookieDomain / /,但似乎没有任何改善......
【解决方案3】:

我遇到了这个确切的问题,并尝试了此处提到的所有其他方法,但均未成功。最后一个难题是将以下内容添加到 Apache 的 SSL 虚拟主机配置中:

RequestHeader set X-Forwarded-Proto "https"

我在 https://github.com/expressjs/session/issues/251 的最后一个 cmets 中发现了这颗特殊的宝石

所以总的来说,我为修复它而实施的事情如下:

  1. Apache 配置更改:

RequestHeader set X-Forwarded-Proto "https" ProxyPassReverseCookiePath / /

  1. Node 应用程序的更改。

app.enable('trust proxy');

【讨论】:

    【解决方案4】:

    查看被转发的会话 cookie 并了解为什么您的浏览器在代理时不重新发送它应该很简单——域或路径可能是错误的。

    Re: 你后来的 cmets——也许你确实设置了“ProxyPassReverseCookieDomain //”而不是使用域作为参数?

    ProxyPreserveHost 也可能间接为您工作,但修复 cookie 更好。

    【讨论】:

    • 我尝试使用实际 URL 设置 ProxyPassReverseCookieDomain,但似乎没有解决任何问题。正如您所说,ProxyPreserveHost 很方便(实际上解决了我遇到的另一个问题)。我已经比较了两个域上的请求,来自 api.domain.com 的响应标头始终包含一个 Set-Cookie 标头,而 localhost:2000 在初始请求中只有一次...
    • 不是网址,域名。
    • ProxyPassReverseCookieDomain 参数对我来说似乎倒退了。后端发出了什么 set-cookie? apache 代理将其转换为什么 set-cookie? cookie 是否被退回?提示,使用数据包捕获。
    【解决方案5】:

    使用此配置可​​在节点 0.6.17 上维护我的会话 ID,表示为 3.0.0rc4。最初我在虚拟主机中有以下内容,但即使更改为匹配您的配置,它仍然有效。

    ServerName api
    ServerAlias api.internal.local
    

    我得到一个维护的 Set-cookie connect.sid。

    【讨论】:

    • apache版本是httpd-2.2.3
    • 我希望它会那么简单 - 但据我所知,唯一的区别是 Apache 版本!目前我无法轻松切换版本,但如果这改变了任何内容,我会感到震惊......
    【解决方案6】:

    这发生在我们身上,我不认为反向 cookie 的东西可以帮助我们解决问题。

    我试过了: app.use("信任代理");

    无济于事。

    但是使用

    app.use("trust proxy");
    app.set("trust proxy", 1);
    

    工作。

    希望这对遇到代理 cookie 问题的人有所帮助。

    【讨论】:

    • 这可能会破坏您的应用程序。应用使用需要中间件功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    • 2018-02-09
    • 1970-01-01
    • 2012-02-09
    相关资源
    最近更新 更多