何时以及如何在你的本地开发环境中使用 HTTPS

大海我来了

共 5015字,需浏览 11分钟

 · 2021-02-02

翻译:布兰
作者: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 个问题展开:

  1. 何时需要在本地开发环境中使用 HTTPS?
  2. 如何在本地开发环境中使用 HTTPS?

何时需要在本地开发环境中使用 HTTPS

在本地开发时,默认情况下使用 http://localhostService Workers, Web 认证 API, 以及一些别的等都可以工作。然而,在以下情况下,你需要使用 HTTPS 进行本地开发:

  • 在所有浏览器中以一致的方式设置安全 cookie。你需要在本地设置一个 Secure 或 SameSite: none 或具有 __Host 前缀的 cookie。对于所有浏览器,仅在 HTTPS上 设置安全 cookie,而不在 http://localhost 上设置安全  cookie。并且由于 SameSite: none__Host 也要求 cookie 是安全的,因此在本地开发站点上设置此类 cookie 也需要 HTTPS。

    在本地设置安全cookie时,并非所有浏览器的行为都相同!例如,Chrome和Safari不在本地主机上设置安全cookie,但Firefox设置了。在Chrome中,这被视为错误。

  • 调试混合内容问题。你需要在本地调试仅在 HTTPS 网站上发生的问题,而不是在 HTTP 网站上,甚至在 http://localhost 上都不会发生,例如混合内容问题。

  • 使用 HTTP/2 和更高版本。

  • 使用需要 HTTPS 的第三方库或 API,比如 OAuth;

  • 你使用的不是本地主机,而是本地开发的自定义主机名,例如 mysite.example。通常,这意味着你已经覆盖了本地主机文件。在这种情况下,即使 Chrome,Edge,Safari 和 Firefox 是本地站点,默认情况下也不认为 mysite.example 是安全的。因此,它的行为不会像 HTTPS 站点那样。

何时使用 HTTPS 进行本地开发

如何在本地开发环境中使用 HTTPS

你可能会遇到一些特殊情况,比如 http://localhost 网站的行为不像 HTTPS 网站,或者你可能只是想使用一个不是 http://localhost 网站的自定义网站名称。

推荐使用 mkcert

mkcert 地址:https://github.com/FiloSottile/mkcert

要将 HTTPS 与你的本地开发站点一起使用并访问 https://localhosthttps://mysite.example(自定义主机名),你需要 TLS 证书。但是浏览器不会仅仅认为任何证书有效:你的证书需要由浏览器信任的实体(称为受信任的证书颁发机构(CA))签名。

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

  • 如果你使用 HTTPS 在浏览器中打开本地运行站点,你的浏览器将检查本地开发服务器的证书;
  • 当看到证书已经由 mkcert 生成的证书颁发机构签名时,浏览器检查它是否注册为受信任的证书颁发机构;
  • mkcert 被列为受信任的权威,因此浏览器信任该证书并创建一个 HTTPS 连接。

mkcert 工作原理图

mkcert (及其类似的工具)提供了几个好处:

  • mkcert 专门用于创建符合浏览器认为有效的证书,它保持更新以满足需求和最佳实践。这就是为什么你不必使用复杂的配置或参数运行 mkcert 命令来生成正确的证书;
  • mkcert 是一个跨平台的工具,团队中的任何人都可以使用它。

mkcert 是我们推荐的用于为本地开发创建 TLS 证书的工具。你也可以查看其他选项。

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

注意事项:

  • 不要导出或共享文件 rootCA-key.pem,因为当你在执行 mkcert -install 的时候,它会自动创建;攻击者获得这个文件可以为你访问的任何站点创建路径上的攻击。他们可以拦截从你的机器发送到任何网站的安全请求,比如你的银行、医疗服务提供商或社交网络。如果你想知道它被放到哪里才是安全的,可以执行 mkcert -CAROOT
  • mkcert 仅仅只是被我们用于开发环境,切不可让最终用户去使用 mkcert 命令;
  • 所有团队成员都应该独自安装和运行 mkcert 命令(不能够存储或者共享 CA 和 证书)。

设置

  1. 安装 mkcert(仅需一次):按照说明在你的操作系统上安装 mkcert:
brew install mkcert
  1. 将 mkcert 添加到本地根 CA 中,在终端运行如下命令:
mkcert -install

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

  1. 为你的站点生成一个由 mkcert 签名的证书。在终端中,导航到站点的根目录或者你希望证书位于的任何目录,然后执行:
mkcert localhost

如果你使用一个自定义的主机名,比如 mysite.example,运行:

mkcert mysite.example

上面的命令做了两件事:

  • 为指定的主机名生成证书;
  • 让 mkcert (在步骤2中添加为本地 CA)签署此证书。

到这步为止,你的证书已经就绪,并由浏览器本地信任的证书颁发机构签名。你差不多完成了,但是你的服务器还不知道你的证书!

  1. 配置你的服务器。现在需要告诉服务器使用 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...}
// - s 使用 HTTPS 运行服务器,-c 设置证书,-k 设置密钥
http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem
  • 使用 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
    |--...

那么你的开始脚本应该是这样的:

"scripts": {
    "start""HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start"
  1. OK,你已经完成配置了。在你的浏览器中打开 https://localhost 或者 https://mysite.example 你使用 HTTPS 在本地运行你的网站。你不会看到任何浏览器警告,因为你的浏览器将 mkcert 信任为本地证书颁发机构。

自签名证书

你还可以决定不使用像 mkcert 这样的本地证书颁发机构,而是自己签署证书。

不过,得小心这种方法的几个缺陷:

  • 浏览器不信任你作为证书颁发机构,它们会显示你需要手动绕过的警告。在 Chrome 中,你可以使用这个标志 #allow-insecure-localhost,自动绕过这个警告;
  • 如果你在不安全的网络中工作,这是不安全的;
  • 自签名证书的行为方式与受信任证书不完全相同;
  • 这并不一定比使用像 mkcert 这样的本地 CA 更容易或更快;
  • 如果不在浏览器上下文中使用此技术,则可能需要禁用服务器的证书验证。忽略在生产中重新启用它将是危险的。

当使用自签名证书时,会显示警告浏览器

为什么浏览器不相信自签名证书

如果你在浏览器中使用 HTTPS 打开本地运行站点,你的浏览器将检查本地开发服务器的证书。当它看到证书是你自己签署的时候,它会检查你是否注册为受信任的证书颁发机构。因为你不是,所以你的浏览器不能信任证书; 它会显示一个警告,告诉你你的连接不安全。你可能会自行承担风险ーー如果你这样做,将创建一个 HTTPS 连接。

为什么浏览器不相信自签名证书

由普通证书颁发机构签署的证书

你还可以找到基于拥有一个实际的证书颁发机构(而不是本地的证书颁发机构)来签署证书的技术。

如果你正在考虑使用这些技巧,请记住以下几点:

  • 与使用像 mkcert 这样的本地 CA 技术相比,你需要做更多的安装工作;
  • 你需要使用你控制的有效域名。这意味着你不能够使用实际的证书颁发机构:
    • localhost 以及其他的保留域名,比如 example 或者 test;
    • 任何你不能控制的域名;
    • 无效的顶级域名

反向代理

使用 HTTPS 访问本地运行站点的另一个选择是使用反向代理,比如 ngrok。需要考虑的几点:

  • 任何人都可以访问你的本地开发网站,只要你与他们分享一个由反向代理创建的 URL。这可以是非常方便的时候,你的项目演示给客户!如果你的项目很敏感,这也可能是一个缺点;
  • 你可能需要考虑价格;
  • 浏览器中新的安全措施可能会影响这些工具的工作方式。

感谢阅读

  1. 如果你觉得这篇文章对你有所帮助的话,来个分享、点赞、在看三连吧,让更多的人看到。
  2. 关注公众号「大海我来了」,回复 666 领取前端进阶资料,定期为你推送前端干货文章。
  3. 添加本人微信「bulandent」,拉你进前端技术交流群和大厂同学一起交流学习。


浏览 95
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报