【问题标题】:How to prevent HTTPS error between Apache server and Node Express?如何防止 Apache 服务器和 Node Express 之间的 HTTPS 错误?
【发布时间】:2020-06-01 16:32:20
【问题描述】:

我已将一台旧笔记本电脑改用于运行 Ubuntu Server 18.04。在我的本地网络上,我为这台笔记本电脑分配了一个固定 IP 192.168.0.36,这样我就可以从我的主机轻松地通过 SSH 连接到它。

我在这台机器上使用 Apache 服务器来托管一个用 React 编写的网站(单页应用程序是使用 npm run build 构建的,然后复制到 /var/www/html/)。

我还在笔记本电脑上运行了一个 Express 服务器,侦听端口 3305(使用 node index.js 运行),该服务器与本地 MariaDb RDBMS 实例接口,并在调用时将 JSON 中继回网站。

当我在家中执行此操作时,我正在使用 noip.com 为我提供一个不会在每次我的 ISP 动态更改我的 IP 时更改的 URL。

这在 http 下一切正常;但是我希望添加 https 加密,因此使用 LetsEncrypt 的 certbot 将证书添加到我的 Apache 配置中。

不幸的是,现在当我查看我的 React 页面的 https 版本时,没有从数据库中提取任何数据,并且浏览器给了我以下错误:

混合内容:“https://xxxx.hopto.org”处的页面通过 HTTPS 加载,但请求了不安全的资源“http://192.168.0.36:3305/contract/”。此请求已被阻止;内容必须通过 HTTPS 提供。

这很简单 - 但也令人困惑。侦听端口 3305 的 Express 服务器落后于在本地计算机上运行的 Apache,因此暗示“值得信赖”。

我很确定问题归结为我如何尝试连接我的 React 应用程序和这个 Express 服务器,它是这样完成的:

App.js(React 网站)

getContract = _ => {
        fetch('http://192.168.0.36:3305/contract/')
            .then(response => response.json())
            .then(response => this.setState({ contract_list: response.data }))
            .catch(err => console.error(err))
    }

index.js(节点快速服务器)

const app = express();

const connection = mysql.createConnection({
    host: config.host,
    user: config.user,
    password: config.password,
    database: config.database
});
app.use(cors());
app.get('/', (req,res) => {
    res.send('go to /contract to see contracts')
});
const SELECT_ALL_CONTRACT_QUERY = 'SELECT * FROM contract';
app.get('/contract', (req, res) => {
    connection.query(SELECT_ALL_CONTRACT_QUERY, (err, results) => {
        if(err) {
            return res.send(err)
        }
        else {
            return res.json({
                data: results
            })
        }
    });
});
app.listen(3305, () => {
    console.log('Db server listening on port 3305')
});

我尝试更改 App.js,使其从 http://localhost:3305/contract 获取,但这根本无法连接。我也试过让 Express 服务器提供 https,但这涉及到一个自签名证书,这只会导致不同的错误。

我的预感是我需要深入了解我的 Apache 配置并让它知道它正在查看本地计算机而不是外部计算机,但我对此没有任何经验......

感谢任何帮助。

【问题讨论】:

    标签: node.js apache express https


    【解决方案1】:

    经过大量阅读,我找到了答案,它确实存在于 Apache 配置中:

    1。将 App.js fetch 修改为相对链接

    使用我上面的代码示例:

    App.js(React 网站)

    getContract = _ => {
            fetch('/api/contract/')
                .then(response => response.json())
                .then(response => this.setState({ contract_list: response.data }))
                .catch(err => console.error(err))
        }
    

    然后它在引用 URL 的末尾被分块,所以如果你从 https://example.org 调用它,那么它指向的 URL(在上面的例子中)是 https://example.org/api/contract/。有趣的是,是否将反斜杠放在 api 前面似乎并没有什么不同,但我认为这样更有意义。

    2。在 Apache 中安装所需的模块

    在命令行输入:

    sudo a2enmod proxy
    sudo a2enmod proxy_http
    sudo a2enmod proxy_html
    

    3。修改Apache配置

    在两个文件 /etc/apache2/sites-enabled/000-default.conf/etc/apache2/sites-enabled/000-default-le-ssl.conf 添加以下文本(在 标签内):

    ProxyPass /.well-known/ !
    ProxyPass /api http://127.0.0.1:3305
    ProxyPassReverse /api http://127.0.0.1:3305
    ProxyPreserveHost On
    

    第一个文件 (000-default.conf) 将调用重定向到 http(即端口 80)和第二个文件 (000-default-le-ssl.conf)重定向 https(即端口 443)。不确定这些是所有 Apache 设置的配置文件,但它们对我有用。

    这告诉 Apache 以 /api 结尾的 URL 的任何传入流量都应发送到 Express 正在侦听的任何端口(在我的示例中为 3305)上的本地主机(在我的情况下为 127.0.0.1) .

    4。重启 Apache

    sudo systemctl restart apache2


    现在,一旦您对系统管理员之神进行了任何您认为合适的仪式,请尝试使用 URL,它应该可以工作...

    虽然这是几个来源的组合,但最有用的是Proxying Node application through Apache

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-30
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多