强制我的Heroku应用程序使用SSL(https)

54

我在Heroku上成功运行了一个Node应用程序。我购买了一个Expedited SSL证书,一切都正常工作。我访问https...并获得完整的“绿色栏”,证明该站点正在通过https提供服务

但是,非SSL标准的http仍然可用。如何强制应用程序通过https提供服务? 谢谢

11个回答

47

1
兄弟,我已经连续四个月在试图解决这个问题了,你简直是神一样的存在,我欠你我的生命,谢谢。 - Jackie Santana
5
那篇文章中的最后一个代码块非常有效!但请记得将其放在所有express的app.use()之前。 - Holger Ludvigsen
@HolgerL 噢,我希望早点看到你的回复。谢谢! - Yurii Kyparus

31

1
运行得非常顺利 - Raine Revere
在2019年仍然像魔法般运作良好。我曾遇到过一个使用Create-React-App在Heroku上部署并与GoDaddy域名结合使用的问题。需要用express服务器来提供构建文件。 - NewScientists
如果您正在使用Next.js,我已经创建了这个包的中间件版本,因此您不必设置自定义服务器:next-ssl-redirect-middleware - NSjonas
2
2022年 - 对我无效(sslRedirect不是一个函数 - Nitsan BenHanoch

26

我只需使用Cloudflare的“始终使用HTTPS”功能即可实现。只需按照以下步骤操作:

1. 如果您还没有注册,请在Cloudflare上注册

2. 添加您的网站example.com

3. 选择一个计划。(免费计划就足够了)

4. 查看您的DNS记录。如果您已经在Namecheap等地方有一些条目,Cloudflare会尝试自动检测这些记录。重要的是,您至少保留Type A记录,其中包括IPv4地址以及CNAME类型,在这里,Content是来自Heroku应用程序设置中域名的DNS Target。请参阅屏幕截图。

cloudflare_heroku

5. 为了成功激活您的网站,您需要指向Cloudflare的名称服务器,否则Cloudflare将无法管理您的DNS并优化您的网站。删除现有名称服务器,然后将它们替换为Cloudflare的名称服务器。他们还会在页面上显示说明(可能需要48小时才能激活您的网站,但根据我的经验只需要15分钟)。请参见Namecheap的截图示例:

cloudflare_namecheap

6. 进入 SSL/TLS 部分,在 Edge Certificates 部分启用“始终使用 HTTPS”功能。现在,所有使用“http”协议的请求都应该被重定向到“https”

cloudflare_https

奖励1:为了转发没有方案或www的请求,例如如果用户只输入example.comwww.example.com,只需创建一个页面规则将这些请求转发到您的安全URL。为此,请转到“页面规则”部分,点击“创建页面规则”按钮。输入应匹配的URL,并添加设置转发URL和状态代码301-永久重定向。还要按以下方式输入目标URL,并在末尾添加$1以使其正常工作。点击“保存并部署”,您就可以开始了。有关更多详细信息,请查看此处的“高级转发选项”部分(请记住,您可能需要清除缓存才能看到更改)。请参见截图:

cloudflare_page_rule

奖励2: 您购买了另一个域名,只想将其重定向到您的安全主域。例如,您购买了fiveexample.com5example.com,您希望始终将5example.com重定向到https://www.fiveexample.com,无论用户输入什么关于5example.com的内容,例如www.5example.comhttp://5example.com,甚至https://www.5example.com,即使您的第二个域没有ssl。Cloudflare的页面规则也是一种解决方案。只需按照步骤1-5(但在第4步中,您不需要heroku dns目标)为您的第二个域执行此操作。在您遵循了支持所有转发的步骤之后,为您的第二个域添加这三个页面规则。对于.app域也完美适用(请记住,您可能需要清除缓存才能看到更改)。请参见屏幕截图

redirect_second_domain_to_main_domain


这是最佳解决方案。 - zgr024

19

如果有人阅读此帖并遇到同样的问题,我曾经发现我的代码是按照这个顺序编写的,这导致了一些问题:

### old way
app.use(express.static('build'));
app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect(`https://${req.header('host')}${req.url}`)
  } else {
    next();
  }
});

### new way (just swap the order)
app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect(`https://${req.header('host')}${req.url}`)
  } else {
    next();
  }
});
app.use(express.static('build'));

我只需要将express.static('build')放在send app.use方法的下面,一切就正常了!


1
兄弟,你太棒了! - zIronManBox
兄弟,你真是救命恩人 <3 - codeboi

11

7
你需要在Node.js应用程序中添加代码,以便在请求来自HTTP时将请求重定向到HTTPS版本。
根据你使用的框架或工具,思路很简单:
- 检查请求方案 - 如果是http,则重定向到https,并传递相同的请求uri和查询。

1
官方文档条目:Heroku能强制应用使用SSL吗? 本文向您展示如何使用不同的框架/语言在应用程序级别实现重定向。 - Braulio

2
您可以在基础架构层面将HTTP请求重定向到HTTPS,而无需对应用程序进行任何更改。 Edge CDN addon 提供了“重定向HTTP到HTTPS”的选项。
它将AWS CloudFront CDN放置在您的应用程序前面,从而处理重定向。
Heroku路由器没有此功能。

1
截至2019年7月,Heroku支持将HTTPS重定向到其他域名或子域名(重定向不能指向自身)。您只需按照此文章中概述的方式为您的域配置URL记录即可。完整公告可在此处找到。

1

有三件事情需要注意:

  1. Heroku没有内置的HTTP到HTTPS自动重定向功能。
  2. 因此,为了在Heroku部署的应用程序中实现HTTP到HTTPS重定向,您将不得不包含应用程序级别的逻辑。幸运的是,Express JS具有内置特性来完成这个任务。如果您使用Node运行时,请在服务器文件中的所有路由之前挂载以下中间件:
 //HTTP to HTTPS automatic redirect
    const requireHTTPS = (req, res, next) => {
      if (!req.secure && req.get('x-forwarded-proto') !== 'https' && process.env.NODE_ENV !== 'development') {
        return res.redirect('https://' + req.get('host') + req.url);
      }
      next();
    }
    
    app.use(requireHTTPS);

如果您不想使用上述的应用层逻辑,请使用 Cloudflare 的 Always On HTTPS 功能。这是一个免费功能,但需要时间来设置,因为您将需要创建 Cloudflare 帐户并首先使用 Cloudflare 域名服务器来管理自定义域名。

0
使用Node.js和Express:
const app = express();

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

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