NodeJS,Express,我为啥要使用 app.enable('trust proxy');

Posted

技术标签:

【中文标题】NodeJS,Express,我为啥要使用 app.enable(\'trust proxy\');【英文标题】:NodeJS, Express, why should I use app.enable('trust proxy');NodeJS,Express,我为什么要使用 app.enable('trust proxy'); 【发布时间】:2017-02-17 05:02:45 【问题描述】:

我需要将 http 重定向到 https 并找到此代码:

app.enable('trust proxy');
app.use((req, res, next) => 
    if (req.secure) 
        next();
     else 
        res.redirect('https://' + req.headers.host + req.url);
    
);

我正在使用 heroku 来托管我的项目,我注意到 heroku 默认发布了*.herokuapp.com 证书,所以我也可以使用 http 和 https。

当在app.use 回调中查看req.secure 时,没有app.enable('trust proxy')req.secure 始终是false,当我添加app.enable('trust proxy') 时它大约为错误2 次,在https 重定向之后它的开关到true

app.enable('trust proxy'), the docs:

表示应用程序位于前置代理之后,并且要使用 X-Forwarded-* 标头确定连接和 IP 地址 客户的。

我的问题:

为什么我的服务器会在代理之后?(它与颁发的*.herokuapp.com 证书有关吗?),如果有人可以解释所有内容如何组合在一起,我的意思是,为什么我的服务器在代理之后?为什么没有app.enable express 将无法识别(或接受)安全连接?

【问题讨论】:

如果您不在代理后面运行,则不需要。例如,如果您在服务器上运行多个网站,您可能会使用代理。执行此操作时会添加 X-Forwarded-For 标头属性,以便您的代理可以看到原始 url 是什么,最终代理将转到您看到的 localhost。需要它的原因是 X-Forwared-For 可以伪造,没有什么可以阻止客户端添加这些,而不仅仅是代理。所以信任代理应该只在接收端启用,这将在你的防火墙后面。因为你有控制权,所以你不能信任。 @Keith 将其发布为答案,如有必要,提供反向链接:) @Keith 你真的应该发布一个答案,这样我才能接受它,顺便说一句,req.secure 在没有app.enable('trust proxy') 的情况下是false 的原因是内部(在防火墙后面)之间代理和我的服务器通信不安全? @AvielFedida 好的,完成。我现在在我的反向代理上执行所有 SSL 并强制使用 SSL,因为谷歌也会更好地排名 SSL。所以我从来不需要检查 req.secure,因为我基本上在端口 http:80 -> https:443 上有一个完整的重定向。我在反向代理上这样做的另一个原因也是为了性能,它允许反向代理处理加密,我的快速服务器也不需要。 【参考方案1】:

如果您没有在代理后面运行,则不需要。例如,如果您在服务器上运行多个网站,您可能会使用代理。

执行此操作时会添加 X-Forwarded-For 标头属性,以便您的代理可以看到原始 url 是什么,最终代理将转到您看到的 localhost。需要它的原因是 X-Forwared-For 可以伪造,没有什么可以阻止客户端添加这些,而不仅仅是代理。所以信任代理应该只在接收端启用,这将在你的防火墙后面。因为你有控制权,所以你可以相信这一点。

因此,简而言之,如果您的网站在代理后运行,您可以启用它。如果您的网站直接在端口 80 上运行,则您不想信任它。因为发件人可以假装来自本地主机等。

【讨论】:

最后一行符合我的要求

以上是关于NodeJS,Express,我为啥要使用 app.enable('trust proxy');的主要内容,如果未能解决你的问题,请参考以下文章

为啥nodejs express post请求中的“body”为空?

create-react-app + nodejs (express) 服务器

为啥nodejs express服务器在我使用post时返回302?

关于NodeJs为啥要用mongoose操作mongodb

关于NodeJs为啥要用mongoose操作mongodb

为啥我的 jQuery .ajax() 路由的 .done() 方法没有在我的 NodeJS、Express 和 Mongoose 项目中触发?