如何使用HTTPS进行本地开发

locahost.jpeg

在大多数情况下,  http://localhost 可以满足开发需求。在浏览器中,HTTP和HTTPS使用也比较接近。但是在生产环境中,特别是部分APIs的站点,一般HTTP就无法正常访问了,但是http://localhost 是不受影响的。在开发过程中,只有在一些特殊的情况下才需要本地使用HTTPS。比如自定义主机名或跨浏览器的安全cookie。

下面针对localhost做个介绍,以下内容同时对127.0.0.1[::1]有效,因为这几个都是本地的“loopback地址”。当然,为了让文章通俗易懂,我们就不在对地址上加端口号,实际上是这样的格式http://localhost:{PORT} 或者 http://127.0.0.1:{PORT}.

如果您的生产环境使用HTTPS,您又希望本地开发站点类似于HTTPS站点(如果您的生产网站不使用HTTPS,则应优先切换到HTTPS)。 大多数时候,http//localhost开发还是可信任的, 但是在某些情况下,还是需要使用HTTPS来进行一些开发测试。 下面我们来看下怎么实现。


⏩  http与https有什么区别?


使用mkcert证书本地运行HTTPS站点 (推荐) 

不管是https://localhost还是自定义的https://mysite.example 只要想用HTTPS就需要TLS证书。但是证书不是所有浏览器都能通过验证的,需要有浏览器能信任的CA(certificate authority)签名才有效。

您需要做的是创建一个证书,并使用您的设备和浏览器在本地信任的CA对其进行签名。 mkcert是一个可以帮助您通过一些命令来完成此任务的工具。大概的操作流程如下:

  • 如果使用HTTPS在浏览器中打开本地运行的站点,则浏览器将检查本地开发服务器的证书。

  • 当看到该证书已由mkcert生成的证书颁发机构签名时,浏览器将检查它是否已注册为受信任的证书颁发机构。

  • mkcert被列为受信任的机构,因此您的浏览器信任该证书并创建HTTPS连接。

mkcert(和类似工具)具有以下优点:

  • mkcert专门用于创建与浏览器认为有效的证书兼容的证书。 它会不断更新以匹配需求和最佳实践。 这就是为什么您不必运行具有复杂配置或参数的mkcert命令来生成正确的证书的原因!

  • mkcert是跨平台工具。您团队中的任何人都可以使用它。

mkcert是我们推荐的用于为本地开发创建TLS证书的工具。您也可以查看其他选项(比如自签名证书)。

许多操作系统可能包括用于生成证书的库,例如openssl。 与mkcert和类似工具不同,此类库可能无法始终如一地产生正确的证书,可能需要运行复杂的命令,并且不一定是跨平台的。


注意事项

  • 切勿导出或共享文件rootCA-key.pem mkcert在运行mkcert -install时自动创建。 拥有此文件的攻击者可以为您可能访问的任何站点创建路径攻击。 他们可以拦截从您的计算机到任何站点(您的银行,医疗保健提供者或社交网络)的安全请求。 如果您需要知道rootCA-key.pem的位置以确保安全,请运行mkcert -CAROOT

  • 仅将mkcert用于开发目的,并且通过扩展,决不要要求最终用户运行mkcert命令。

  • 开发团队:团队中的所有成员应分别安装和运行mkcert(而不是存储和共享CA和证书)。


操作说明

安装mkcert

以下操作以macOS为例。

brew install mkcert
brew install nss # if you use Firefox

将mkcert添加到本地根CA。 

在您的终端中,运行以下命令:

mkcert -install

这将生成本地证书颁发机构(CA)。您的mkcert生成的本地CA仅在设备上本地受信任。

为您的站点生成一个由mkcert签名的证书。

在您的终端中,导航到站点的根目录或您想要证书位于的任何目录。然后执行

mkcert localhost

如果您使用的是mysite.example这样的自定义主机名,请运行:

mkcert mysite.example

上面的命令做了两件事:

  • 为您指定的主机名生成一个证书

  • 让mkcert(您已在步骤2中作为本地CA添加)签署此证书。

现在,您的证书已准备就绪,并由您的浏览器在本地信任的证书颁发机构签名。 您已经快完成了,但是您的服务器尚不知道您的证书!

配置您的服务器

现在,您需要告诉服务器使用HTTPS(因为开发服务器默认情况下倾向于使用HTTP)并使用刚创建的TLS证书。 如何执行此操作完全取决于您的服务器。几个例子:

👩🏻‍💻 With node:

server.js (替换 {PATH/TO/CERTIFICATE...} 和 {PORT}):

// AAA为require
const https = AAA('https');
const fs = AAA('fs');
const options = {
 key: fs.readFileSync('{PATH/TO/CERTIFICATE-KEY-FILENAME}.pem'),
 cert: fs.readFileSync('{PATH/TO/CERTIFICATE-FILENAME}.pem'),
};
https
 .createServer(options, function (req, res) {
   // server code
 })
 .listen({PORT});

👩🏻‍💻 With http-server:

如下所示启动服务器(替换{PATH/TO/CERTIFICATE ...}):

http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem

-S使用HTTPS运行服务器,而-C设置证书,-K设置密钥。

👩🏻‍💻 With a React development server:

如下编辑您的package.json,并替换{PATH/TO/CERTIFICATE ...}

"scripts": {
"start": "HTTPS=true SSL_CRT_FILE={PATH/TO/CERTIFICATE-FILENAME}.pem SSL_KEY_FILE={PATH/TO/CERTIFICATE-KEY-FILENAME}.pem react-scripts start"

例如,如果您为站点的根目录中的localhost创建了一个证书,如下所示:

|-- my-react-app
    |-- package.json
    |-- localhost.pem
    |-- localhost-key.pem
    |--...

然后,您的启动脚本应如下所示:

"scripts": {
"start": "HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start"

除了以上的,还可以以下的一些,这边就不再一一介绍。

  • Angular development server

  • Python

✨ 你完成了!

在浏览器中打开https//localhosthttps//mysite.example您正在使用HTTPS在本地运行站点。您将不会看到任何浏览器警告,因为您的浏览器将mkcert信任为本地证书颁发机构。