Как включить локальный HTTPS для разработки
Большинство фронтенд-разработчиков считают, что для использования браузерных API, таких как service workers или геолокация, необходим локальный HTTPS. На самом деле это заблуждение — браузеры уже считают localhost безопасным контекстом, поэтому эти API прекрасно работают через обычный HTTP. Но существуют реальные ситуации, когда локальный HTTPS действительно необходим: тестирование URL обратного вызова OAuth, работа с cookies в среде, похожей на production, разработка с использованием пользовательского имени хоста или точное воспроизведение поведения production-окружения. В этой статье показано, как правильно настроить локальный HTTPS.
Ключевые моменты
- Браузеры считают
localhostбезопасным контекстом, поэтому большинство API, требующих безопасного контекста, работают без HTTPS локально. - Локальный HTTPS полезен для тестирования поведения cookies как в production, обратных вызовов OAuth, пользовательских имён хостов или доступа с мобильных устройств.
- Самоподписанные сертификаты вызывают постоянные предупреждения браузера — используйте
mkcertдля создания доверенного локального центра сертификации. - Никогда не коммитьте файл
rootCA-key.pemи установитеNODE_EXTRA_CA_CERTS, если Node.js должен доверять вашему локальному CA.
Когда локальный HTTPS действительно необходим
Прежде чем создавать сертификат, спросите себя, действительно ли он вам нужен. http://localhost считается потенциально доверенным источником всеми основными браузерами. Service workers, доступ к камере и большинство API безопасного контекста работают без какой-либо настройки HTTPS. Вы можете проверить это поведение в данных совместимости браузеров на webstatus.dev.
Реальный локальный HTTPS может понадобиться, когда:
- Вы тестируете поведение cookies в условиях, соответствующих production, особенно с
Securecookies на именах хостов, отличных от localhost - Вы тестируете потоки OAuth или OIDC с URL обратного вызова, которые должны соответствовать зарегистрированному HTTPS-источнику
- Вы разрабатываете с использованием пользовательского имени хоста, например
app.localhostвместоlocalhost - Вам нужно тестировать на мобильном устройстве в той же сети
- Ваш фронтенд и бэкенд работают локально и должны взаимодействовать через HTTPS для воспроизведения поведения production
Если ничего из этого не применимо, пропустите настройку и оставьте всё как есть.
Почему самоподписанные сертификаты плохо работают
Очевидный первый порыв — сгенерировать самоподписанный сертификат. Проблема в том, что браузеры не доверяют сертификатам, если они не подписаны известным центром сертификации. Самоподписанный сертификат вызывает предупреждение “Ваше подключение не защищено”, и вам придётся нажимать кнопку каждый раз — или полностью отключить проверку сертификатов, что создаёт плохие привычки.
Правильный подход — создать локальный центр сертификации, которому доверяют ваша система и браузеры, а затем выпускать сертификаты, подписанные этим CA. Именно это и делает mkcert.
Настройка доверенных локальных сертификатов с помощью mkcert
mkcert — это инструмент с нулевой конфигурацией, который создаёт локальный CA, регистрирует его в системном хранилище доверия и выпускает сертификаты, подписанные им. Браузеры доверяют этим сертификатам без предупреждений.
Шаг 1: Установите mkcert
На macOS:
brew install mkcert
brew install nss # required for Firefox
На Linux используйте ваш пакетный менеджер или следуйте руководству по установке mkcert. На Windows используйте Chocolatey или Scoop.
Шаг 2: Зарегистрируйте локальный CA
mkcert -install
Это создаёт корневой CA и добавляет его в системное хранилище доверия. Это нужно сделать только один раз на каждой машине.
Шаг 3: Сгенерируйте сертификат для вашего имени хоста
mkcert localhost
# или для пользовательского имени хоста:
mkcert app.localhost
Это создаст два файла: сертификат (.pem) и приватный ключ (-key.pem). Не добавляйте их в систему контроля версий — добавьте их в .gitignore.
Discover how at OpenReplay.com.
Настройка dev-сервера для использования HTTPS
Способ передачи сертификата вашему dev-серверу зависит от используемых инструментов.
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)
Важно: Никогда не делитесь и не коммитьте файл
rootCA-key.pem, который генерирует mkcert. Если кто-то получит этот файл, он сможет выпускать доверенные сертификаты для любого домена на вашей машине. Выполнитеmkcert -CAROOT, чтобы узнать, где он хранится.
Важное замечание по безопасности в Node.js
Если ваш локальный бэкенд делает HTTPS-запросы к другим локальным сервисам, Node.js не будет автоматически доверять вашему mkcert CA — он использует собственный встроенный список доверенных центров сертификации, а не системное хранилище доверия. Исправьте это, установив переменную окружения:
export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
Добавьте это в профиль вашей оболочки (.bashrc, .zshrc и т.д.), чтобы настройка сохранялась между сеансами.
Заключение
Включение HTTPS локально — это не то, что нужно каждому проекту, но когда это действительно необходимо, самоподписанный сертификат не подойдёт. mkcert даёт вам правильно доверенные localhost-сертификаты за несколько минут, без предупреждений браузера или обходных путей. Настройте один раз, укажите вашему dev-серверу на сгенерированные файлы, и ваше локальное окружение будет вести себя точно так же, как production.
Часто задаваемые вопросы
Нет. Все основные браузеры считают localhost безопасным контекстом, поэтому service workers, Geolocation API и другие функции безопасного контекста работают через обычный HTTP на localhost. Локальный HTTPS нужен только если вы тестируете поведение cookies как в production, обратные вызовы OAuth для HTTPS-источника, разрабатываете с пользовательским именем хоста или тестируете на мобильном устройстве по сети.
Да, mkcert безопасен для локальной разработки. Он создаёт центр сертификации, которому доверяет только ваша машина. Ключевой риск — это файл rootCA-key.pem, который он генерирует. Если кто-то другой получит этот файл, он сможет выпускать сертификаты, которым будет доверять ваш браузер. Никогда не коммитьте его в систему контроля версий и выполните mkcert -CAROOT, чтобы проверить, где он хранится.
Node.js не использует хранилище доверия вашей операционной системы. Он полагается на собственный встроенный список центров сертификации, поэтому не будет автоматически доверять вашему mkcert CA. Установите переменную окружения NODE_EXTRA_CA_CERTS, указывающую на ваш файл rootCA.pem от mkcert, и добавьте её в профиль вашей оболочки, чтобы она сохранялась между сеансами терминала.
Да. Любой dev-сервер или фреймворк, который принимает файлы 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.