翻译:布兰 作者:Maud Nalpas https://web.dev/when-to-use-local-https/ https://web.dev/how-to-use-local-https/
“在这篇文章中,关于本地主机的语句也适用于
127.0.0.1
和[::1]
,因为它们都描述了本地计算机地址,也称为“回送地址”。另外,为简单起见,未指定端口号。因此,当你看到http://localhost
时,将其读取为http://localhost:{PORT}
或http://127.0.0.1:{PORT}
。
如果你的生产网站使用 HTTPS,那么你会希望本地开发站点的表现也会和 HTTPS 站点一样。在大多数情况下,你可以相信 http://localhost
的行为类似于 HTTPS 站点。但是在某些情况下,你需要使用 HTTPS 在本地运行站点。
所以本文将针对 2 个问题展开:
在本地开发时,默认情况下使用 http://localhost
。Service Workers
, Web 认证 API, 以及一些别的等都可以工作。然而,在以下情况下,你需要使用 HTTPS 进行本地开发:
SameSite: none
或具有 __Host
前缀的 cookie。对于所有浏览器,仅在 HTTPS上 设置安全 cookie,而不在 http://localhost
上设置安全 cookie。并且由于 SameSite: none
和 __Host
也要求 cookie 是安全的,因此在本地开发站点上设置此类 cookie 也需要 HTTPS。
“在本地设置安全cookie时,并非所有浏览器的行为都相同!例如,Chrome和Safari不在本地主机上设置安全cookie,但Firefox设置了。在Chrome中,这被视为错误。http://localhost
上都不会发生,例如混合内容问题。mysite.example
。通常,这意味着你已经覆盖了本地主机文件。在这种情况下,即使 Chrome,Edge,Safari 和 Firefox 是本地站点,默认情况下也不认为 mysite.example
是安全的。因此,它的行为不会像 HTTPS 站点那样。何时使用 HTTPS 进行本地开发
你可能会遇到一些特殊情况,比如 http://localhost 网站的行为不像 HTTPS 网站,或者你可能只是想使用一个不是 http://localhost 网站的自定义网站名称。
“mkcert 地址:https://github.com/FiloSottile/mkcert
要将 HTTPS 与你的本地开发站点一起使用并访问 https://localhost
或 https://mysite.example
(自定义主机名),你需要 TLS 证书。但是浏览器不会仅仅认为任何证书有效:你的证书需要由浏览器信任的实体(称为受信任的证书颁发机构(CA))签名。
而你需要做的就是创建一份证书,并使用你的设备和浏览器在本地信任的 CA 对其进行签名。mkcert 是一个可以帮助你通过一些命令来完成此任务的工具。运作方式如下:
mkcert 工作原理图
mkcert (及其类似的工具)提供了几个好处:
mkcert 是我们推荐的用于为本地开发创建 TLS 证书的工具。你也可以查看其他选项。
许多操作系统可能包含用于产生证书的库,比如 openssl。与 mkcert 和类似的工具不同,这些库可能不能始终生成正确的证书,可能需要运行复杂的命令,而且不一定是跨平台的。
rootCA-key.pem
,因为当你在执行 mkcert -install
的时候,它会自动创建;攻击者获得这个文件可以为你访问的任何站点创建路径上的攻击。他们可以拦截从你的机器发送到任何网站的安全请求,比如你的银行、医疗服务提供商或社交网络。如果你想知道它被放到哪里才是安全的,可以执行 mkcert -CAROOT
。brew install mkcert
mkcert -install
这将生成一个本地证书颁发机构(CA)。你的 mkcert 生成的本地 CA 在你的设备上仅受本地信任。
mkcert localhost
如果你使用一个自定义的主机名,比如 mysite.example,运行:
mkcert mysite.example
上面的命令做了两件事:
到这步为止,你的证书已经就绪,并由浏览器本地信任的证书颁发机构签名。你差不多完成了,但是你的服务器还不知道你的证书!
{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});
{PATH/TO/CERTIFICATE...}
:// - s 使用 HTTPS 运行服务器,-c 设置证书,-k 设置密钥
http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem
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"
https://localhost
或者 https://mysite.example
你使用 HTTPS 在本地运行你的网站。你不会看到任何浏览器警告,因为你的浏览器将 mkcert 信任为本地证书颁发机构。你还可以决定不使用像 mkcert 这样的本地证书颁发机构,而是自己签署证书。
不过,得小心这种方法的几个缺陷:
#allow-insecure-localhost
,自动绕过这个警告;当使用自签名证书时,会显示警告浏览器
如果你在浏览器中使用 HTTPS 打开本地运行站点,你的浏览器将检查本地开发服务器的证书。当它看到证书是你自己签署的时候,它会检查你是否注册为受信任的证书颁发机构。因为你不是,所以你的浏览器不能信任证书; 它会显示一个警告,告诉你你的连接不安全。你可能会自行承担风险ーー如果你这样做,将创建一个 HTTPS 连接。
为什么浏览器不相信自签名证书
你还可以找到基于拥有一个实际的证书颁发机构(而不是本地的证书颁发机构)来签署证书的技术。
如果你正在考虑使用这些技巧,请记住以下几点:
localhost
以及其他的保留域名,比如 example 或者 test;使用 HTTPS 访问本地运行站点的另一个选择是使用反向代理,比如 ngrok。需要考虑的几点: