本地开发如何使用HTTPS
本文关于localhost的表述,同样适用于127.0.0.1与[::1],因为两者都表示本机地址,也称“回环地址”。为简化说明,没有写出端口号。因此看到http://localhost时,应理解为http://localhost:{PORT}或http://127.0.0.1:{PORT}。
如果生产网站使用HTTPS,就会希望本地开发网站的行为也像HTTPS网站。如果生产网站尚未使用HTTPS,应优先切换到HTTPS。大多数时候,可以信赖http://localhost具有类似HTTPS网站的行为;但在某些情况下,仍需在本地通过HTTPS运行网站。下面看看如何实现。
需要快速操作说明,或已经读过本文?直接跳到速查表。
使用mkcert在本地通过HTTPS运行网站,推荐
要让本地开发网站使用HTTPS,并通过https://localhost或自定义主机名https://mysite.example访问,需要TLS证书。但浏览器不会认为任意证书都有效:证书必须由浏览器信任的实体签名,这个实体称为受信任的证书颁发机构,CA。
需要创建证书,并使用设备和浏览器在本地信任的CA为它签名。mkcert可以通过几条命令完成这些工作,其工作方式如下:
- 通过HTTPS在浏览器中打开本地运行的网站时,浏览器会检查本地开发服务器的证书。
- 发现证书由mkcert生成的CA签名后,浏览器检查该CA是否已注册为受信任的证书颁发机构。
- mkcert被列为受信任机构,因此浏览器信任证书并建立HTTPS连接。

mkcert及类似工具具有多项优点:
- mkcert专门创建符合浏览器有效证书标准的证书,并随要求与最佳实践更新。因此不必通过复杂配置或参数运行mkcert命令,也能生成正确证书。
- mkcert是跨平台工具,团队中的任何人都可以使用。
我们推荐使用mkcert创建本地开发用TLS证书,也可以查看其他选项。
很多操作系统包含用于生成证书的库,例如openssl。与mkcert及类似工具不同,这些库可能无法始终生成正确证书,可能需要复杂命令,也不一定跨平台。
注意
设置
- 安装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上述命令完成两件事:为指定主机名生成证书,并让已经在第2步添加为本地CA的mkcert为证书签名。
现在证书已经准备好,并由浏览器在本地信任的CA签名。只差最后一步:服务器还不知道这张证书。
- 配置服务器。
现在需要告诉服务器使用HTTPS,因为开发服务器通常默认使用HTTP,并使用刚创建的TLS证书。
具体方法取决于服务器。下面给出几个例子。
使用Node:
编辑
server.js,替换{PATH/TO/CERTIFICATE...}与{PORT}:const https = require('https'); const fs = require('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});使用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设置密钥。使用React开发服务器:
按以下方式编辑
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 |--...那么
start脚本应如下:"scripts": { "start": "HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start"其他示例:
- 完成!
在浏览器中打开
https://localhost或https://mysite.example:网站已经在本地通过HTTPS运行。因为浏览器信任mkcert这个本地CA,所以不会出现浏览器警告。
使用mkcert:速查表
mkcert简要步骤
要让本地开发网站通过HTTPS运行:
- 设置mkcert。
尚未安装时先安装,例如在macOS上:
brew install mkcertWindows与Linux的安装方法请查看安装mkcert。
然后创建本地CA:
mkcert -install - 创建受信任证书。
mkcert {YOUR HOSTNAME e.g. localhost or mysite.example}这会创建有效证书,并由mkcert自动签名。
- 配置开发服务器使用HTTPS及第2步创建的证书。
- 完成!现在可以在浏览器中访问
https://{YOUR HOSTNAME},不出现警告。
本地通过HTTPS运行网站:其他选项
自签名证书
也可以不使用mkcert这样的本地CA,而是自行签署证书。
这种方式有以下问题:
- 浏览器并不信任你作为CA,因此会显示需要手动绕过的警告。在Chrome中,可以使用
#allow-insecure-localhost标志自动绕过localhost上的警告。这种做法确实有些取巧。 - 在不安全网络中工作时,这不安全。
- 自签名证书的行为与受信任证书并不完全相同。
- 它不一定比使用mkcert这样的本地CA更简单或更快。
- 在浏览器以外使用该技术时,可能需要对服务器禁用证书验证。如果在生产环境中忘记重新启用,会很危险。

为什么浏览器不信任自签名证书?
通过HTTPS在浏览器中打开本地网站时,浏览器会检查本地开发服务器的证书。发现证书由你自己签名后,它会检查你是否注册为受信任CA。因为没有注册,浏览器无法信任该证书,因此显示连接不安全的警告。你可以自行承担风险继续访问;若继续,就会建立HTTPS连接。

由常规证书颁发机构签名的证书
还可能找到使用真正的CA,而不是本地CA,为证书签名的技术。
考虑这些方法时,需要注意:
- 与mkcert这样的本地CA方案相比,需要更多设置工作。
- 必须使用你拥有控制权的有效域名。因此,不能让真正的CA为以下名称签发证书:
反向代理
通过HTTPS访问本地网站的另一个办法,是使用反向代理,例如ngrok。
需要考虑:
- 将反向代理生成的URL分享给别人后,任何持有该URL的人都可以访问本地开发网站。这在向客户演示项目时很方便;如果项目敏感,也可能是缺点。
- 可能需要考虑价格。
- 浏览器中的新安全措施可能影响这些工具的工作方式。
浏览器标志,不推荐
使用mysite.example这样的自定义主机名时,可以利用Chrome标志强制把mysite.example视为安全。应避免这样做,因为:
- 必须百分之百确认
mysite.example始终解析为本地地址,否则可能泄露生产凭据。 - 这个技巧无法用于跨浏览器调试。
感谢所有审阅者与贡献者的贡献和反馈,尤其是Ryan Sleevi、Filippo Valsorda、Milica Mihajlija与Rowan Merewood。
原文主图背景由@anandu提供,来自Unsplash,经过编辑。
来源与许可
作者:Maud Nalpas。来源:web.dev:Use HTTPS for local development,2021年1月25日。本版为中文翻译,源码保持原文。所保存官方仓库版本将正文按CC BY 3.0、代码示例按Apache 2.0许可提供,完整条款见官方仓库LICENSE。主图另有上列图片署名。











暂无评论内容