使用 HTTPS 进行本地开发

大多数情况下,出于开发目的,http://localhost 的行为类似于 HTTPS。不过,在一些特殊情况(例如自定义主机名或跨浏览器使用安全 Cookie)下,您需要明确设置开发网站的行为方式,使其类似于 HTTPS,以准确表示网站在生产环境中的运行。(如果您的生产网站不使用 HTTPS,请优先考虑改用 HTTPS)。

本页介绍了如何使用 HTTPS 在本地运行您的网站。

如需简要说明,请参阅 mkcert 快速参考。**

使用 mkcert 通过 HTTPS 在本地运行您的网站(推荐)

如需在本地开发网站上使用 HTTPS 并访问 https://localhost 或 https://mysite.example(自定义主机名),您需要一个由您的设备和浏览器信任的实体(称为可信证书授权机构 (CA))签名的 TLS 证书。在创建 HTTPS 连接之前,浏览器会检查开发服务器的证书是否由可信 CA 签名。

我们建议您使用跨平台 CA mkcert 来创建证书并为其签名。如需了解其他实用选项,请参阅使用 HTTPS 在本地运行您的网站:其他选项

许多操作系统都包含用于创建证书的库,例如 openssl。但是,它们比 mkcert 更复杂、更可靠,且不一定是跨平台的,因此较大规模的开发者团队不容易使用它们。

初始设置

  1. 安装 mkcert(仅一次)。请按照相关instructions在您的操作系统上安装 mkcert。例如,在 macOS 上:
    brew install mkcert
    brew install nss # if you use Firefox
    
  2. 将 mkcert 添加到本地根 CA。在终端中,运行以下命令:
    mkcert -install
    

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

  3. 为您的网站生成由 mkcert 签名的证书。在终端中,转到网站的根目录或要在其中保存证书的任何目录。然后运行以下命令:
    mkcert localhost
    

    如果您使用的是自定义主机名(如 mysite.example),请运行以下命令:

    mkcert mysite.example
    

    此命令会执行两项操作:

    • 为您指定的主机名生成证书。
    • 让 mkcert 对证书进行签名。

    您的证书现已准备就绪,并由浏览器在本地信任的证书授权机构签名。

  4. 将服务器配置为使用您刚创建的 TLS 证书 HTTPS。具体操作步骤取决于您的服务器。下面是一些示例:🥂? 🚌? 使用节点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 设置密钥。

    ◼ noopener 带 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"
    

    🥂? 🚌? 其他示例

  5. 在浏览器中打开 https://localhost 或 https://mysite.example,仔细检查您的网站是否使用 HTTPS 在本地运行。您不会看到任何浏览器警告,因为浏览器将 mkcert 视为本地证书授权机构。

mkcert 快速参考

mkcert 快速参考

如需使用 HTTPS 运行本地开发网站,请执行以下操作:

  1. 设置 mkcert。如果您尚未安装 mkcert,请先安装(例如在 macOS 上):
    brew install mkcert
    
    

    如需了解适用于 Windows 和 Linux 的说明,请查看 install mkcert

    然后,创建本地证书授权机构:

    mkcert -install
    
  2. 创建可信证书。
    mkcert {YOUR HOSTNAME e.g. localhost or mysite.example}
    

    这将创建一个 mkcert 自动签名的有效证书。

  3. 将开发服务器配置为使用 HTTPS 和您在第 2 步中创建的证书。

你现在可以在浏览器中访问 https://{YOUR HOSTNAME},且系统不会显示警告

使用 HTTPS 在本地运行您的网站:其他选项

以下是设置证书的其他方法。这通常比使用 mkcert 更复杂或风险更大。

自签名证书

您还可以决定不使用 mkcert 等本地证书授权机构,而是自行为证书签名。这种方法存在一些缺陷:

  • 浏览器不会信任您作为证书授权机构,因此会显示您需要手动绕过的警告。在 Chrome 中,您可以使用 #allow-insecure-localhost 标志在 localhost 时自动绕过此警告。
  • 如果您使用不安全的网络,此项操作不安全。
  • 这未必比使用 mkcert 等本地 CA 更简单或更快。
  • 自签名证书的行为方式与可信证书不同。
  • 如果您未在浏览器环境中使用此方法,则需要为服务器停用证书验证。忘记在生产环境中重新启用它会导致安全问题。

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

如果您未指定证书,React 的和 Vue 的开发服务器 HTTPS 选项会在后台创建自签名证书。此过程很快,但会带来同样的浏览器警告和自签名证书的其他隐患。幸运的是,您可以使用前端框架的内置 HTTPS 选项,并指定使用 mkcert 或类似方式创建的本地受信证书。如需了解详情,请参阅结合使用 mkcert 和 React 示例。

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

由常规证书授权机构签名的证书

您也可以使用由官方 CA 签名的证书。这会带来以下复杂问题:

  • 与使用 mkcert 等本地 CA 技术时相比,您需要完成更多设置工作。
  • 您需要使用由您控制的有效域名。这意味着您不能将官方 CA 用于以下情况:
    • localhost 以及其他预留域名(如 example 或 test)。
    • 不归您控制的任何域名。
    • 顶级域名无效。有关详情,请参阅有效的顶级域名列表

反向代理

使用 HTTPS 访问本地运行的网站的另一种方法是使用反向代理,例如 ngrok。这带来了以下风险:

  • 您与之共享反向代理网址的任何人都可以访问您的本地开发网站。这有助于向客户演示您的项目,但也可让未经授权的人员分享敏感信息。
  • 某些反向代理服务按使用量收费,因此价格可能是您选择服务的一个因素。
  • 浏览器中新的安全措施可能会影响这些工具的工作方式。

标志(不推荐)

如果您在 Chrome 中使用诸如 mysite.example 之类的自定义主机名,可以使用标志来强制浏览器认为 mysite.example 是安全的。请避免这样做,原因如下:

  • 您需要完全确定 mysite.example 始终解析为本地地址。否则,您可能会泄露生产凭据。
  • 此标志仅适用于 Chrome,因此无法跨浏览器进行调试。

何时使用 HTTPS 进行本地开发

在本地开发时,请默认使用 http://localhost。Service Worker、Web Authentication API 等等。 但在以下情况下,您需要使用 HTTPS 进行本地开发:

  • 以一致的方式跨浏览器设置安全 Cookie
  • 调试混合内容问题
  • 使用 HTTP/2 及更高版本
  • 使用需要 HTTPS 的第三方库或 API
  • 使用自定义主机名

为了避免遇到意外问题,您应该让本地开发网站尽可能像生产网站一样运行。因此,如果您的生产网站使用 HTTPS,则您希望本地开发网站的行为像 HTTPS 网站一样。

浏览器会以特殊方式处理 http://localhost尽管它是 HTTP,但它大多表现得像 HTTPS 网站

http://localhost 支持 Service Worker、Sensor API、Authentication API、Payment 以及需要特定安全保证的其他功能,其行为方式与 HTTPS 网站上的完全相同。

您可能会遇到以下特殊情况:http://localhost 的行为方式与 HTTPS 网站不同,或者您可能只是想使用不是 http://localhost 的自定义网站名称。

在以下情况下,您需要使用 HTTPS 进行本地开发:

  • 您需要在本地设置 Cookie,即 SecureSameSite:none 或带有 __Host 前缀的 Cookie。Secure Cookie 仅在 HTTPS 上设置,而非在所有浏览器上都在 http://localhost 上设置。此外,由于 SameSite:none 和 __Host 还要求将 Cookie 设为 Secure,因此在本地开发网站上设置此类 Cookie 也需要使用 HTTPS。
  • 您需要在本地对仅出现在 HTTPS 网站上(而不出现在 HTTP 网站上,甚至不出现在 http://localhost)上的问题进行本地调试,例如混合内容问题。
  • 您需要在本地测试或重现 HTTP/2 或更高版本特有的行为。例如,如果您需要在 HTTP/2 或更高版本上测试加载性能。不支持不安全的 HTTP/2 或更高版本,即使在 localhost 上也是如此。
  • 您需要在本地测试需要使用 HTTPS 的第三方库或 API(例如 OAuth)。
  • 您使用的不是 localhost,而是用于本地开发的自定义主机名,例如 mysite.example。通常,这意味着您替换了本地 hosts 文件:
    修改 hosts 文件以添加自定义主机名。

     

    在这种情况下,默认情况下,Chrome、Edge、Safari 和 Firefox 不会将 mysite.example 视为安全网站,即使它是本地网站也是如此。因此,其行为方式与 HTTPS 网站不同。

  • 其他情况!此列表并不详尽,但如果您遇到未在此处列出的情况,就会了解:http://localhost 中的内容将会中断,或者与正式版网站的行为方式不完全一样。🙃

在所有这些情况下,您都需要使用 HTTPS 进行本地开发。

如果您使用的是自定义主机名(例如,要修改 hosts 文件),请执行以下操作

  • 请勿使用像 mysite 这样的裸主机名,因为如果存在恰好使用同一名称 (mysite) 的顶级域名 (TLD),那么您会遇到问题。也不太可能:2020 年,顶级域名有超过 1,500 个,并且名单还在不断增加。coffeemuseumtravel 以及许多大型公司名称(甚至可能是您所在的公司!)都是顶级域名。点击此处可查看完整列表
  • 请仅使用您自己的或预留用于此用途的域名。如果您没有自己的网域,则可以使用 test 或 localhost (mysite.localhost)。test 在浏览器中不会受到特殊处理,但 localhost 却有特殊处理:Chrome 和 Edge 开箱就支持 http://<name>.localhost,当 localhost 支持时,它会安全地运行。不妨试试看:在本地主机上运行任何网站,然后在 Chrome 或 Edge 中访问 http://<whatever name you like>.localhost:<your port>。我们可能很快也会在 Firefox 和 Safari 中使用此功能。您可以执行此操作(具有类似 mysite.localhost 的子网域)是因为 localhost 不仅仅是主机名:它也是一个完整的 TLD(例如 com)。

 

 

阅读余下内容
 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号