Используйте HTTPS для локальной разработки

В большинстве случаев http://localhost ведет себя как HTTPS для целей разработки. Однако есть особые случаи, например использование собственных имен хостов или защищенных файлов cookie в разных браузерах, когда вам нужно явно настроить сайт разработки так, чтобы он вел себя как HTTPS, чтобы точно представлять, как ваш сайт работает в рабочей среде. Если на вашем сайте не используется протокол HTTPS, перейдите на него как можно скорее.

В этой статье рассказывается, как запустить сайт локально с использованием HTTPS.

Краткие инструкции приведены в кратком руководстве по mkcert**.

Запустите свой сайт локально с HTTPS, используя mkcert (рекомендуется)

Чтобы использовать HTTPS на локальном сайте разработки и получить доступ к https://localhost или https://mysite.example (собственное имя хоста), вам нужен TLS-сертификат, подписанный организацией, которой доверяют ваше устройство и браузер. Такая организация называется доверенным центром сертификации. Перед созданием HTTPS-подключения браузер проверяет, подписан ли сертификат сервера разработки доверенным центром сертификации.

Для создания и подписания сертификата рекомендуем использовать кросс-платформенный центр сертификации mkcert. Другие полезные варианты описаны в разделе Запуск сайта локально с HTTPS: другие варианты.

Во многих операционных системах есть библиотеки для создания сертификатов, например openssl. Однако они более сложны и менее надежны, чем mkcert, и не обязательно являются кроссплатформенными, что делает их менее доступными для больших команд разработчиков.

Настройка

  1. Установите mkcert (только один раз).

    Следуйте инструкциям по установке mkcert для вашей операционной системы. Например, в macOS:

    brew install mkcert
    brew install nss # if you use Firefox
    
  2. Добавьте mkcert в локальные корневые центры сертификации.

    В терминале выполните следующую команду:

    mkcert -install
    

    Будет создан локальный центр сертификации. Локальный ЦС, созданный с помощью mkcert, является доверенным только локально, на вашем устройстве.

  3. Сгенерируйте сертификат для своего сайта, подписанный mkcert.

    В терминале перейдите в корневой каталог сайта или в каталог, в котором вы хотите хранить сертификат.

    Затем выполните следующую команду:

    mkcert localhost
    

    Если вы используете собственное имя хоста, например mysite.example, выполните следующую команду:

    mkcert mysite.example
    

    Эта команда выполняет два действия:

    • Создает сертификат для указанного имени хоста.
    • Позволяет mkcert подписать сертификат.

    Сертификат готов и подписан центром сертификации, которому доверяет ваш браузер.

  4. Настройте сервер так, чтобы он использовал HTTPS и созданный вами сертификат TLS.

    Способ реализации зависит от вашего сервера. Вот несколько примеров:

    👩🏻‍💻 С помощью Node.js

    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 – ключ.

    👩🏻‍💻 С сервером разработки 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

    Инструкции по установке mkcert для Windows и Linux можно найти здесь.

    Затем создайте локальный центр сертификации:

    mkcert -install
  2. Создайте доверенный сертификат.

    mkcert {YOUR HOSTNAME e.g. localhost or mysite.example}

    Это создаст действительный сертификат, который mkcert подпишет автоматически.

  3. Настройте сервер разработки на использование HTTPS и сертификата, созданного на шаге 2.

Теперь вы можете заходить на сайт https://{YOUR HOSTNAME} в браузере без предупреждений.

</div>

Как запустить сайт локально с HTTPS: другие варианты

Ниже описаны другие способы настройки сертификата. Обычно они сложнее или рискованнее, чем использование mkcert.

Самозаверяющий сертификат

Вы также можете не использовать локальный центр сертификации, например mkcert, и подписать сертификат самостоятельно. У этого подхода есть несколько недостатков:

  • Браузеры не доверяют вам как центру сертификации, поэтому они будут показывать предупреждения, которые вам нужно будет обходить вручную. В Chrome можно использовать параметр #allow-insecure-localhost, чтобы автоматически пропускать это предупреждение в localhost.
  • Это небезопасно, если вы работаете в незащищенной сети.
  • Это не обязательно проще или быстрее, чем использование локального ЦС, такого как mkcert.
  • Самозаверяющие сертификаты работают не так, как доверенные.
  • Если вы не используете этот метод в контексте браузера, вам нужно отключить проверку сертификата для своего сервера. Если забыть включить его в рабочей среде, возникнут проблемы с безопасностью.
Скриншоты предупреждений, которые показывают браузеры при использовании самозаверяющего сертификата.
Предупреждения, которые браузеры показывают при использовании самозаверяющего сертификата.

Если вы не укажете сертификат, то параметры HTTPS сервера разработки React и Vue создадут самозаверяющий сертификат. Это быстро, но вы столкнетесь с теми же предупреждениями браузера и другими проблемами, что и при использовании самозаверяющих сертификатов. К счастью, вы можете использовать встроенный параметр HTTPS для фреймворков внешнего интерфейса и указать локально доверенный сертификат, созданный с помощью mkcert или аналогичного инструмента. Дополнительную информацию можно найти в примере mkcert с React.

Почему браузеры не доверяют самозаверяющим сертификатам?

Если вы откроете локальный сайт в браузере по протоколу HTTPS, браузер проверит сертификат локального сервера разработки. Если сертификат подписан вами, система проверяет, зарегистрированы ли вы как доверенный центр сертификации. Поскольку вы этого не делали, браузер не может доверять сертификату и показывает предупреждение о том, что подключение не защищено. Если вы продолжите, соединение HTTPS будет установлено, но вы будете действовать на свой страх и риск.

Диаграмма, показывающая, почему браузеры не доверяют самозаверяющимся сертификатам.
Почему браузеры не доверяют самозаверяющимся сертификатам

Сертификат, подписанный обычным центром сертификации

Вы также можете использовать сертификат, подписанный официальным центром сертификации. Это может привести к следующим проблемам:

  • Вам придется выполнить больше действий, чем при использовании локального ЦС, например mkcert.
  • Вам нужно использовать действительное доменное имя, которым вы управляете. Это означает, что вы не можете использовать официальные центры сертификации для следующих целей:

Обратный прокси-сервер

Ещё один способ получить доступ к локально запущенному сайту по протоколу HTTPS – использовать обратный прокси-сервер, например ngrok. Это связано со следующими рисками:

  • Все, у кого есть URL обратного прокси-сервера, могут получить доступ к вашему локальному сайту разработки. Это может быть полезно для демонстрации проекта клиентам, но также может позволить неавторизованным пользователям делиться конфиденциальной информацией.
  • Некоторые обратные прокси-серверы платные, поэтому при выборе сервиса следует учитывать его стоимость.
  • Новые меры безопасности в браузерах могут повлиять на работу этих инструментов.

Если вы используете в Chrome собственное имя хоста, например mysite.example, вы можете использовать параметр, который заставит браузер считать mysite.example безопасным. Не рекомендуем так делать по следующим причинам:

  • Вы должны быть полностью уверены, что mysite.example всегда разрешается в локальный адрес. В противном случае вы рискуете раскрыть учетные данные рабочей среды.
  • Этот параметр работает только в Chrome, поэтому вы не сможете выполнять отладку в других браузерах.

Благодарим всех, кто помогал нам в работе над этой статьей, особенно Райана Сливи (Ryan Sleevi), Филиппо Вальсорду (Filippo Valsorda), Милицу Михайлию (Milica Mihajlija) и Роуэна Меревуда (Rowan Merewood). 🙌