如何让我的Next.js和Express网站在SSL上运行

4
我们有一个基于Next.js和Express的网站。这个网站运行在一个cPanel服务器上,使用Apache作为主服务器,同时nginx作为反向代理服务器。
我需要在这个网站上安装ssl证书,但是我对配置方式感到很困惑。
我的server.js文件内容如下:
const express = require('express')
const next = require('next')
const https = require('https');
const fs = require('fs');
//const forceSSL = require('express-force-ssl')

var ssl_options = {
 key: fs.readFileSync('/home/myreactsite.key'),
 cert: fs.readFileSync('/home/myreactsite.crt'),
};

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

const favicon = require('serve-favicon')
const path = require('path')

app.prepare()
.then(() => {
 const server = express()
 server.use(favicon(path.join(__dirname, 'static', 'images', 'favicon.ico')))

 server.get('*', (req, res) => {
  return handle(req, res)
})

server.listen(3007, (err) => {
   if (err) throw err
   console.log('> Ready on http://localhost:3007')
 })

var httpsServer = https.createServer(ssl_options,server).listen('8445', (err) => {
  if (err) throw err
  console.log('> Ready on https://localhost:8445')
})
})
.catch((ex) => {
 console.error(ex.stack)
 process.exit(1)
})

Apache运行在8080端口,Nginx运行在80端口,Next.js同时运行在3007和8445端口(我更喜欢用它来实现SSL)。

我的Apache配置包含以下内容,以隐藏3007端口:

<Proxy *>
   Order deny,allow
   Allow from all
</Proxy>
ProxyPass / http://myreactsite.com:3007/

如果我通过http://myreactsite.com访问该网站,它可以正常工作。但是,如果我通过https://myreactsite.com访问,则无法正常工作,尽管我可以通过指定端口号https://myreactsite.com:8445访问https版本。
我想让它在不指定https端口的情况下正常工作。
如何使我的网站强制所有页面使用https而不指定端口?

你不能让反向代理处理SSL终止吗? - robertklep
将代理部分的端口从3007更改为8445,然后重新启动Apache。 - Bogdan Stoica
2个回答

5

您可能希望使用Apache来处理所有的SSL,并监听443端口,然后代理到您的3007端口。尝试使用以下配置:

<VirtualHost *:443>
  ProxyPreserveHost On
  ProxyRequests Off
  ServerName myreactsite.com
  ServerAlias myreactsite.com
  ProxyPass / http://0.0.0.0:3007/
  ProxyPassReverse / http://0.0.0.0:3007/
  SSLEngine On
  SSLProxyEngine On
  SSLCertificateFile /home/myreactsite.crt
  SSLCertificateKeyFile /home/myreactsite.key
</VirtualHost>

如果要重定向所有 HTTP 流量,则:

<VirtualHost *:80>
  ServerName myreactsite.com
  Redirect / https://myreactsite.com/  
</VirtualHost>

谢谢@fabian,这个方法很有效。你让我今天过得很愉快 :) 此外,我还在nginx.conf中添加了以下行:return 301 https://$host$request_uri; 这样所有非http请求都将被重定向到https。 - Janith Punna
很高兴能够帮到你!你也可以使用Apache来重定向所有HTTP流量。我更新了我的答案,它取自我的博客文章 - Fabian Schultz
谢谢@fabian :) - Janith Punna
有没有一种方法可以使用https节点模块? - Umair Ahmed

0

根据@fabian的评论,如果有帮助的话,我将发布我的工作配置...

在apache.conf中为站点的443虚拟主机部分添加以下行:

ProxyPreserveHost On
ProxyRequests Off
<Proxy *>
    Order deny,allow
    Allow from all
</Proxy>
ProxyPass / http://example.com:3000/
ProxyPassReverse / http://example.com:3000/
SSLProxyEngine On
#To redirect to https and www version
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]

另外,在nginx虚拟主机文件中添加了以下行用于该网站:
server {
  ...
  ...
#To redirect all http requests to https+www
return 301 https://www.example.com$request_uri;
  ...
  ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接