昨天把 biz-to-me 升级到支持 HTTPS 了,为此研究了一下如何让 Heroku 上跑的 Node.js 应用支持 HTTPS。我发现并没有任何文章描述这个具体的流程,只有零碎的信息,所以在此记录一下。

首先,Heroku 应用要支持 HTTPS 必须要是付费的等级,最便宜的是每月 $7 的 Hobby 级别。把应用升级到 Hobby 级别后,我们在应用设置里面添加的域名就能自动获得 SSL 证书,这个过程是全自动的,无需手动操作。(全自动不意味着实时,每次添加新域名都需要等一段时间才会看到「ACM Status」这一栏变成「Ok」的状态。背后实际使用的证书签发机构其实是 Let’s Encrypt。)

一般 Heroku 应用的「DNS Target」是 app-name.herokuapp.com,需要留意的是一旦升级到支持 SSL 后这一栏的内容会改变,变成 app.example.com.herokudns.com,也就是在 herokudns.com 之前加上应用的整个域名。如果之前 DNS 的 CNAME 指向还是 herokuapp.com,那必须记得更新为 herokudns.com,否则 herokuapp.com 不会使用正确的 SSL 证书提供服务。(herokuapp.com 永远只会用 *.herokuapp.com 的证书提供服务,而 herokudns.com 会根据前缀选择正确的证书。)

在大多数情况下,Heroku 应用升级到支持 HTTPS 后应用代码不需要更新,这是因为 SSL 连接在 Heroku 的负载均衡器那里就种终止了,负载均衡器用明文 HTTP 跟应用连接所以应用本身不需要具备处理 HTTPS 的能力。(Node.js 有 https 模块,但调用时需要访问证书私钥,所以还是用 http 模块比较方便。)如果需要在 Node.js 中判断上游请求是不是 HTTPS,可以通过读取 X-Forwarded-Proto header 来实现,这个 header 的取值可以是 "http""https",例如说在 biz-to-me 中我就通过这一行代码来进行判断。

最后简述一下如何验证配置是否成功。最简单的方法自然是测试一下 HTTPS 服务是否正常工作。biz-to-me 的服务很简单,如果我打开一个 http(s)://*.catchen.biz/* 的 URL,它返回 301 把我重定向到 http(s)://*.catchen.me/*。这篇文章的 URL 是 https://chinese.catchen.me/2018/07/heroku-nodejs-https.html,如果我 curl -i 对应的 catchen.biz URL 能得到正确的 301 重定向那就是成功了。

$ curl -i https://chinese.catchen.biz/2018/07/heroku-nodejs-https.html
HTTP/1.1 301 Moved Permanently
Server: Cowboy
Connection: keep-alive
Location: https://chinese.catchen.me/2018/07/heroku-nodejs-https.html
Date: Sun, 01 Jul 2018 21:29:36 GMT
Transfer-Encoding: chunked
Via: 1.1 vegur Permanently moved to <a href="https://chinese.catchen.me/2018/07/heroku-nodejs-https.html">https://chinese.catchen.me/2018/07/heroku-nodejs-https.html</a>.

留意 Location header 的值是 HTTPS 开头的而非 HTTP,因为在 Node.js 代码更新到支持 HTTPS 之前我们也能得到类似的 301 响应,只不过 Location 永远都只是 HTTP 的。

如果 curl -i 因为证书不正确而出错的话,可以用 curl --insecure 来忽略证书验证 Node.js 代码。然后再用 curl -v 来查看证书,看看到底为什么证书错误。curl -v 的结果关键看这一段:

* Server certificate:
* subject: CN=cantonese.catchen.biz
* start date: Jul 1 04:44:37 2018 GMT
* expire date: Sep 29 04:44:37 2018 GMT
* subjectAltName: host "chinese.catchen.biz" matched cert's "chinese.catchen.biz"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.

如果 Heroku 应用只添加了一个域名,subject 那一行的域名必须是这个唯一域名。如果看到 subject 那一行显示的是 *.herokuapp.com,那意味着我们需要把域名 CNAME 改为 herokudns.com,或者是域名变更还没生效。(变更还没在本地 DNS 生效的话,可以用 curl --resolve 在本地强行覆盖。)如果 Heroku 应用有多个域名,subject 会是其中一个,但 subjectAltName 会有多个域名,至少应该找到有一个对的。

最后,如果你喜欢我的文章的话,欢迎通过邮件RSS/Atom 订阅我的博客。

Heroku + Node.js + HTTPS的更多相关文章

  1. Node.js HTTPS

    稳定性: 3 - 稳定 HTTPS 是基于 TLS/SSL 的 HTTP 协议.在 Node 里作为单独的模块来实现. 类: https.Server 这是 tls.Server 的子类,并且和 ht ...

  2. Node.js之路【第一篇】初识Node.js

    什么是Node.js 1.Node.js就是运行在服务端的JavaScrip. 2.Node.js是一个基于Chrome JavaScrip运行时简历的一个平台. 3.Node.js是一个非阻塞I/O ...

  3. rabbitmq, windows/linux, c/c++/node.js/golang/dotnet

    官网:http://www.rabbitmq.com/ zeromq 相当于 message backbone,而rabbitmq相当于message broker.有的应用系统中,二者并存. (1) ...

  4. aix 上搭建node.js 环境

    下载nodejs:ibm-4.4.3.0-node-v4.4.3-aix-ppc64.bin IBM已经适配最新版本的node.js  :https://developer.ibm.com/node/ ...

  5. Node.js:JavaScript脚本运行环境

    Node.js https://nodejs.org/ 2016-08-03

  6. 安装Node.js

    1.window下安装Node.js 安装git,方便使用命令行. 网址:http://www.git-scm.com/download/ 下载后直接安装即可 接着安装Node.js https:// ...

  7. 【 js 模块加载 】深入学习模块化加载(node.js 模块源码)

    一.模块规范 说到模块化加载,就不得先说一说模块规范.模块规范是用来约束每个模块,让其必须按照一定的格式编写.AMD,CMD,CommonJS 是目前最常用的三种模块化书写规范.  1.AMD(Asy ...

  8. 使用node.js 脚手架搭建Vue项目

    1.安装node.js https://nodejs.org/zh-cn/ 下载安装node.js 在命令行测试 node -v 输出版本号说明安装成功 2.使用npm更新安装cpnm npm ins ...

  9. Node.js作web服务器总结

    1.为什么Node.js用JS开发    Node.js 含有一系列内置模块,使得程序可以脱离 Apache HTTP Server 或 IIS,作为独立服务器运行. 首先,我们都清楚的是,同时接收数 ...

随机推荐

  1. ERP项目应该由谁来主导?

    前段时间在朋友圈看到了别人分享的公众号,主要是谈ERP项目应该由谁来主导的问题.文章的观点认为应该由哪个部门主导ERP的判断标准如下: 1.应该由一个期望上进的部门主导ERP项目: 2.应该由一个有话 ...

  2. [翻译]LVM中逻辑卷的最大大小限制

    前言: 本文是对这篇博客Maximum Size Of A Logical Volume In LVM的翻译,敬请尊重原创和翻译劳动成果,那些随意转载的大爷们,好歹也自觉注明出处.谢谢! 英文原文地址 ...

  3. 如何获取Azure AD tenant的tenant Id?

          一般情况下,Azure AD用户知道自己tenant域名,因为域名是账户的后缀,例如:contoso.onMicrosoft.com.如果你还不了解什么是Azure AD tenant,可 ...

  4. Spring MVC HelloWorld入门及运行机制 (一)

    完整的项目案例: springmvc.zip 介绍 SpringMVC是一款Web MVC框架. 它跟Struts框架类似,是目前主流的Web MVC框架之一. 文章通过实例来介绍SpringMVC的 ...

  5. web前端(5)—— 常用标签2

    以下三个不仅是常用标签了,还非常重要,所以请务必好好看,重要性从高到低: 盒模型div div标签是最常用最重要的,它可以把web页面分割成很多的小块分别管理 测试代码: <!DOCTYPE h ...

  6. Mybatis 学习---${ }与#{ }获取输入参数的区别、Foreach的用法

    一.Mybatis中用#{}和${}获取输入参数的区别 1.“#{}“和“${}”都可以从接口输入中的map对象或者pojo对象中获取输入的参数值.例如 <mapper namespace=&q ...

  7. 一次线上问题引发的对于C#中相等判断的思考

    线上报来一个问题,说用户的数据丢失了.开发经过紧张的调查.终于找到了原因. if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex)) ...

  8. windows7家庭版,专业版,旗舰版,企业版版本区别

    Windows 7包含6个版本,分别为Windows 7 Starter(初级版).Windows 7 Home Basic(家庭普通版).Windows 7 Home Premium(家庭高级版). ...

  9. MATLAB一元线性回归分析

    MATLAB一元线性回归分析应用举例 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ huigui.m function [b,bint,r,rint, ...

  10. vue-cli笔记

    总是忘,留个笔记. vue-cli A simple CLI for scaffolding Vue.js projects. Installation Prerequisites: Node.js ...