node.js - 为了将域切换到HTTPS,我是否需要更改Apache或Node.js应用程序?

标签 node.js apache ssl reverse-proxy

我有一个在我的域上运行的Web应用程序。首先,我有一个常规的HTTP站点,该站点运行在服务器上的端口8082上,而Apache服务器(使用虚拟主机)将请求从端口80重定向到localhost:8082

现在,我获得了一个SSL证书,该证书试图与我的网站一起安装。我在Node中制作了一个HTTPS服务器,在https://localhost:8082上一切正常。

但是后来我尝试通过HTTPS为我的域提供服务。我尝试编辑虚拟主机文件以使用证书,但是我认为我没有正确编写它。另外,我尝试使它将HTTP重定向到HTTPS,但没有用。

我该怎么办?我应该在Node中运行HTTP还是HTTPS服务器,我应该在Apache虚拟主机配置中添加什么?

这是我的虚拟主机文件:

<VirtualHost *:80>
        ServerName www.domain.com
        Redirect permanent / https://www.domain.com
</VirtualHost>

<VirtualHost *:443>

        ServerName domain.com
        ServerAlias www.domain.com

        SSLEngine On
        SSLProxyEngine On
        SSLCertificateFile "/home/USERNAME/Projects/NODEAPP/chained.pem"
        SSLCertificateKeyFile "/home/USERNAME/Projects/NODEAPP/domain.key"

        ProxyPreserveHost On
        ProxyRequests off

        <Proxy *>
                Order deny,allow
                Allow from all
        </Proxy>

        <Location />
                ProxyPass http://localhost:8082/

                ProxyPassReverse http://localhost:8082/
        </Location>

</VirtualHost>

最佳答案

(警告:我对您的问题的理解是,您希望https://www.domain.com出现在浏览器的网址栏中,而不是https://www.domain.com:8082。如果不是这种情况,则下面的很多内容是错误的,但可能仍会帮助您理解您的问题更好。)

背景

(aka,HTTP设计速成课程,因为我认为您不太了解正在发生的事情,但是如果您这样做,请随时跳过:)

我认为您对Apache的操作有一个误解-主要是因为您是在说它正在“重定向”请求。

HTTP重定向是状态代码在3xx范围内的任何(?)响应,它告诉您的浏览器所请求的资源已移动到其他地方。例如,假设http://example.com/foo曾经存在,但此后已移至http://example.org/bar(请注意.com.org的区别)。如果在URL栏中键入http://example.com/foo,浏览器将向/foo请求example.com(特别是它将发送HTTP GET请求)。然后,example.com将HTTP响应发送回浏览器,将其重定向到http://example.org/bar。然后,浏览器将向/bar发送对example.org的HTTP GET请求,并获取包含该资源的响应。

这是一个图:

Step 1:

-------------                                   --------------------------
|           |                                   |                        |
|  Browser  | -------- HTTP GET /foo ---------> | example.com web server |
|           | <-- HTTP 301 Moved Permanently -- |                        |
-------------                                   --------------------------

Step 2:

-------------                        --------------------------
|           |                        |                        |
|  Browser  | --- HTTP GET /bar ---> | example.org web server |
|           | <---- HTTP 200 OK ---- |                        |
-------------                        --------------------------


现在,这是事情。那不是你在做什么,也可能不是你想做什么。您正在做的事情称为反向代理,这是每当Web服务器(在您的情况下为Apache)接收到请求时,它将转发到其他地方的请求。在原始(全HTTP)设置中,Web浏览器将向Apache请求www.domain.com,然后Apache只需将该请求(几乎没有修改)转发到http://localhost:8082。如下图:

Step 1:

-------------                        ----------                        ------------------
|           |                        |        |                        |                |
|           | ----- HTTP GET / ----> |        |                        |                |
|  Browser  |                        | Apache | ----- HTTP GET / ----> | localhost:8082 |
|           |                        |        | <---- HTTP 200 OK ---- |                |
|           | <---- HTTP 200 OK ---- |        |                        |                |
-------------                        ----------                        ------------------

Step 2:

There is no step 2. BOOM.


这里要注意的真正重要的事情是浏览器没有“看到” Node.js,而是看到了另一端的Apache。同样,Node.js不会“看到”浏览器,而是看到Apache(尽管通常Apache会使用有关浏览器连接的详细信息来扩充请求-例如,参见X-Forwarded-For标头)。

这是HTTP设计的故意部分-HTTP请求和响应语义并不暗示有关如何处理请求的内部实现细节。这就是HTTP如此强大的原因。它使您可以创建非常复杂的设置-思考您正在做的事情,但要更大的规模并使用更多的组件-然后通过向外界显示的简单,统一的界面抽象出这种复杂性:您的URL层次结构与HTTP请求/响应周期。

如何解决您的实际问题

既然我们已经确定了您要尝试做的事情,这就是您的问题所在:您正在将Node.js在说什么协议与Apache在说什么协议(以及外界在看什么)混为一谈。

您的最终目标是让人们通过HTTPS连接到您的网站,对吗?在那种情况下,您不需要Node.js讲HTTPS,因为直接与Node.js对话的唯一东西就是Apache。 Apache是​​与浏览器对话的东西,因此Apache是​​使用HTTPS所需要的。理想情况下,您应该让Apache对浏览器讲HTTPS,对HTTP.Node.js讲HTTP-Apache是​​否加密到Node的流量并不重要,因为Node在本地主机上。以图表形式:

-------------                         ----------                        ------------------
|           |                         |        |                        |                |
|           | ----- HTTPS GET / ----> |        |                        |                |
|  Browser  |                         | Apache | ----- HTTP GET / ----> | localhost:8082 |
|           |                         |        | <---- HTTP 200 OK ---- |                |
|           | <---- HTTPS 200 OK ---- |        |                        |                |
-------------                         ----------                        ------------------


因此,请让您的Node应用程序侦听HTTP请求,然后修复您的Apache配置,以使用HTTPS来提供服务,但要向Node后端讲HTTP。

我认为您的配置存在问题,因为您需要在路径两边加上引号,即<Location "/">。或者,在我具有的反向代理配置中,我设置了ProxyPass指令而没有<Location>块,如下所示:

ProxyPass / http://localhost:8082/
ProxyPassReverse / http://localhost:8082/


因此您也可以尝试。

如果仍然无法正常运行,请尝试删除<Proxy> / </Proxy>块-我不确定是否可以这样做,但是我的反向代理配置中没有类似的功能(可以正常工作)-因此它可能会干扰某些东西。

至于您的HTTP到HTTPS重定向,我没有发现任何问题。您确定要连接到www.domain.com而不是domain.com吗?第二台VirtualHost可以同时为两者提供服务,但第一台VirtualHost只能为前者提供服务。

关于node.js - 为了将域切换到HTTPS,我是否需要更改Apache或Node.js应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40835607/

相关文章:

php - 共享主机上的 TTFB 非常高

php - Ubuntu 14.04 服务器 : Apache2 issue with phpMyAdmin

apache - Laravel 5.1 应用程序可以在没有 .htaccess 重写的情况下运行吗?

email - 从无人机服务器发送电子邮件时出错(证书中的负序列号)

ssl - Selenium Webdriver SSL 证书主机名不匹配问题

node.js - 如何在 react 应用程序中重新加载每个页面时停止 firebase re-auth()?

node.js - Babel 将异步到模块方法转换为带有 ES6 映射的 Bluebird

php - 如何使用 Node.js 从 PHP 运行 JS 并返回一个值?

node.js - Electron -mainWindow.webContents.executeJavaScript()使用文件而不是文本