Back

如何为开发环境启用本地 HTTPS

如何为开发环境启用本地 HTTPS

大多数前端开发者认为需要在本地运行 HTTPS 才能使用 Service Worker 或地理定位等浏览器 API。这实际上是一个误解——浏览器已经将 localhost 视为安全上下文,因此这些 API 在纯 HTTP 下也能正常工作。但确实存在一些真正需要本地 HTTPS 的场景:测试 OAuth 回调 URL、在类生产环境中处理 Cookie、使用自定义主机名开发,或精确匹配生产环境行为。本文将向您展示如何干净利落地完成这些设置。

核心要点

  • 浏览器将 localhost 视为安全上下文,因此大多数安全上下文 API 在本地无需 HTTPS 即可工作。
  • 本地 HTTPS 适用于测试类生产环境的 Cookie 行为、OAuth 回调、自定义主机名或移动设备访问。
  • 自签名证书会导致持续的浏览器警告——应使用 mkcert 创建受信任的本地证书颁发机构。
  • 切勿提交 rootCA-key.pem 文件,如果 Node.js 需要信任您的本地 CA,请设置 NODE_EXTRA_CA_CERTS

何时真正需要本地 HTTPS

在使用证书之前,先问问自己是否真的需要。所有主流浏览器都将 http://localhost 视为潜在可信源。Service Worker、摄像头访问和大多数安全上下文 API 无需任何 HTTPS 设置即可工作。您可以在 webstatus.dev 的浏览器兼容性数据中确认这一行为。

在以下情况下,您可能仍需要真正的本地 HTTPS:

  • 您正在测试与生产环境匹配的 Cookie 行为,特别是在非 localhost 主机名上使用 Secure Cookie
  • 您正在测试 OAuth 或 OIDC 流程,回调 URL 必须匹配已注册的 HTTPS 源
  • 您正在使用自定义主机名(如 app.localhost)而非 localhost 进行开发
  • 您需要在同一网络上的移动设备上进行测试
  • 您的前端和后端都在本地运行,必须通过 HTTPS 通信以复现生产环境行为

如果以上情况都不适用,跳过设置,保持简单即可。

为什么自签名证书效果不佳

最直观的做法是生成自签名证书。问题在于:除非证书由已知的证书颁发机构签名,否则浏览器不会信任它。自签名证书会触发”您的连接不是私密连接”警告,您每次都必须点击通过——或者完全禁用证书验证,这会养成不良习惯。

正确的方法是创建一个本地证书颁发机构,让您的系统和浏览器信任它,然后颁发由该 CA 签名的证书。这正是 mkcert 的作用。

使用 mkcert 设置受信任的本地证书

mkcert 是一个零配置工具,可创建本地 CA、将其注册到系统信任存储,并颁发由其签名的证书。浏览器会信任这些证书而不会发出警告。

步骤 1:安装 mkcert

在 macOS 上:

brew install mkcert
brew install nss  # Firefox 需要

在 Linux 上,使用您的包管理器或参考 mkcert 安装指南。在 Windows 上,使用 Chocolatey 或 Scoop。

步骤 2:注册本地 CA

mkcert -install

这会创建一个根 CA 并将其添加到系统的信任存储中。每台机器只需执行一次。

步骤 3:为您的主机名生成证书

mkcert localhost
# 或为自定义主机名:
mkcert app.localhost

这会生成两个文件:证书(.pem)和私钥(-key.pem)。将它们排除在版本控制之外——添加到 .gitignore 中。

配置开发服务器使用 HTTPS

如何将证书传递给开发服务器取决于您使用的工具。

Vite — 最简单的方式,使用 vite-plugin-mkcert:

import mkcert from 'vite-plugin-mkcert'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [mkcert()]
})

该插件会自动处理证书生成和服务器配置。

Vite(手动方式):

import fs from 'fs'
import { defineConfig } from 'vite'

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync('./localhost-key.pem'),
      cert: fs.readFileSync('./localhost.pem'),
    }
  }
})

Next.js — 在最新版本中使用 next dev --experimental-https 标志,或使用相同的证书文件手动配置自定义 Node.js HTTPS 服务器。

Node.js(任何框架):

const https = require('https')
const fs = require('fs')

https.createServer({
  key: fs.readFileSync('localhost-key.pem'),
  cert: fs.readFileSync('localhost.pem'),
}, app).listen(3000)

重要提示: 切勿共享或提交 mkcert 生成的 rootCA-key.pem 文件。如果有人获得该文件,他们可以为您机器上的任何域颁发受信任的证书。运行 mkcert -CAROOT 查找其存储位置。

关于 Node.js 的安全说明

如果您的本地后端向其他本地服务发起 HTTPS 请求,Node.js 不会自动信任您的 mkcert CA——它使用自己内置的受信任颁发机构列表,而非系统信任存储。通过设置环境变量来解决此问题:

export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"

将此添加到您的 shell 配置文件(.bashrc.zshrc 等)中,以便在会话间持久保存。

总结

启用本地 HTTPS 并非每个项目都需要——但当您确实需要时,自签名证书无法胜任。mkcert 可在几分钟内为您提供受信任的 localhost 证书,无需浏览器警告或变通方案。只需设置一次,将开发服务器指向生成的文件,您的本地环境就会与生产环境表现完全一致。

常见问题

不需要。所有主流浏览器都将 localhost 视为安全上下文,因此 Service Worker、地理定位 API 和其他安全上下文功能在 localhost 上通过纯 HTTP 即可工作。只有在测试类生产环境的 Cookie 行为、针对 HTTPS 源的 OAuth 回调、使用自定义主机名开发或通过网络在移动设备上测试时,才需要本地 HTTPS。

是的,mkcert 用于本地开发是安全的。它创建的证书颁发机构仅受您的机器信任。关键风险在于它生成的 rootCA-key.pem 文件。如果其他人获得该文件,他们可以颁发您的浏览器会信任的证书。切勿将其提交到版本控制,运行 mkcert -CAROOT 检查其存储位置。

Node.js 不使用操作系统的信任存储。它依赖自己内置的证书颁发机构列表,因此不会自动信任您的 mkcert CA。将 NODE_EXTRA_CA_CERTS 环境变量设置为指向您的 mkcert rootCA.pem 文件,并将其添加到 shell 配置文件中,以便在终端会话间持久保存。

可以。任何接受 TLS 密钥和证书文件的开发服务器或框架都可以使用。使用 mkcert 生成文件,然后将它们传递给服务器配置。Express、Fastify、Webpack Dev Server 等都支持自定义 HTTPS 选项。vite-plugin-mkcert 插件只是为 Vite 项目自动化了这一步骤。

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay