---
title: Использование протокола HTTPS при разработке в локальной среде
subhead: Иногда может потребоваться использовать протокол HTTPS для локального сайта разработки. Средства и советы, позволяющие сделать это быстро и безопасно.
authors:
  - maudn
date: 2021-01-25
hero: image/admin/ZvW6VM0GEScldWHBvXJ4.jpg
thumbnail: image/admin/OG8YksgOnzGfnurzncWO.jpg
tags:
  - blog
  - security
---

{% Aside 'caution' %} В большинстве случаев узел `http://localhost` делает то, что вам нужно, — в браузерах он обычно ведет себя как HTTPS 🔒. Именно поэтому некоторые API, которые не работают на развернутом HTTP-сайте, будут работать на узле `http://localhost`.

Это означает, что протокол HTTPS следует применять в локальной среде **только в особых случаях** (см. статью «[Когда использовать протокол HTTPS для разработки в локальной среде](/when-to-use-local-https)»), например при работе с пользовательскими именами хостов или безопасными файлами cookie в браузерах. Если это ваш случай, читайте дальше! {% endAside %}

*Все, что говорится в этой публикации об узле `localhost` справедливо и для узлов `127.0.0.1` и `[::1]`, так как последние означают адрес локального компьютера, также называемый петлевым адресом. Кроме того, для простоты мы не будем указывать номера портов.**Поэтому текст `http://localhost` следует читать как `http://localhost:{ПОРТ}` или `http://127.0.0.1:{ПОРТ}`.*

Если на вашем рабочем веб-сайте используется протокол HTTPS, вам, возможно, потребуется, чтобы локальный сайт разработки вел себя **как HTTPS-сайт** (если на вашем рабочем веб-сайте не используется протокол HTTPS, [включите переход на протокол HTTPS в список своих приоритетных задач](/why-https-matters/)). В большинстве случаев вы можете быть уверены, что узел `http://localhost` будет вести себя **как HTTPS-сайт**. Тем не менее [в некоторых случаях](/when-to-use-local-https) может потребоваться, чтобы ваш сайт работал в локальной среде с использованием протокола HTTPS. Давайте посмотрим, как это сделать.

**⏩ Вам нужны краткие инструкции или вы уже были здесь раньше? Перейти к [шпаргалке](#using-mkcert-cheatsheet).**

## Запуск сайта в локальной среде с поддержкой протокола HTTPS с помощью mkcert (рекомендуемый способ)

Чтобы использовать протокол HTTPS для сайта разработки в локальной среде и получить доступ к узлу `https://localhost` или `https://mysite.example` (пользовательское имя хоста), вам понадобится [сертификат TLS](https://en.wikipedia.org/wiki/Public_key_certificate#TLS/SSL_server_certificate). Однако браузеры не считают любые сертификаты допустимыми: сертификат должен быть **подписан** организацией, которой доверяет браузер и которая называется доверенным **[центром сертификации](https://en.wikipedia.org/wiki/Certificate_authority)**.

Вам потребуется создать сертификат и подписать его в центре сертификации, которому **локально доверяют** ваши устройство и браузер. С помощью средства [mkcert](https://github.com/FiloSottile/mkcert) можно сделать это несколькими командами. Вот как оно работает.

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

<figure>{% Img src="image/admin/3kdjci7NORnOw54fMia9.jpg", alt="Схема, на которой показано, как работает средство mkcert.", width="800", height="787" %} <figcaption>Схема, на которой показано, как работает средство mkcert.</figcaption></figure>

Средство mkcert (и аналогичные инструменты) дает несколько указанных ниже преимуществ.

- Средство mkcert предназначено для создания сертификатов, **которые браузеры считают допустимыми**. Оно постоянно обновляется в соответствии с новыми требованиями и рекомендациями. Поэтому для создания нужных сертификатов вам не придется запускать команды mkcert со сложными конфигурациями или аргументами.
- Средство mkcert — кроссплатформенное. Его может использовать любой участник вашей команды.

Мы рекомендуем создавать сертификаты TLS для локальной разработки с помощью средства mkcert. Но вы можете изучить и [другие способы](#running-your-site-locally-with-https-other-options).

В состав многих операционных систем входят библиотеки для создания сертификатов, например [openssl](https://www.openssl.org/). В отличие от mkcert и аналогичных средств такие библиотеки не всегда могут создавать правильные сертификаты. Для их использования, возможно, потребуется выполнять сложные команды, а сами они не всегда кроссплатформенные.

{% Aside 'gotchas' %} Средство mkcert, которое мы рассмотрим в данной публикации, — [такое](https://github.com/FiloSottile/mkcert), а не [такое](https://www.npmjs.com/package/mkcert). {% endAside %}

### Предупреждение

{% Aside 'caution' %}

- Никогда не экспортируйте и никому не передавайте файл `rootCA-key.pem`, который средство mkcert автоматически создает при выполнении команды `mkcert -install`. **Злоумышленник, завладевший этим файлом, будет способен организовывать атаки в пути для любого сайта, который вы можете посетить**. Он сможет перехватывать защищенные запросы с вашего компьютера к любым сайтам — банков, поставщиков медицинских услуг или социальных сетей. Если вам нужно узнать, где расположен файл `rootCA-key.pem`, чтобы убедиться, что он хранится в безопасном расположении, выполните команду `mkcert -CAROOT`.
- Используйте средство mkcert только в **целях разработки** и, соответственно, никогда не просите конечных пользователей выполнять команды mkcert.
- Команды разработчиков: все участники вашей команды должны установить и запускать средство mkcert **по отдельности** (не хранить и не обмениваться центрами сертификации и сертификатами).

{% endAside %}

### Настройка

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

    Следуйте [инструкциям](https://github.com/FiloSottile/mkcert#installation) по установке средства mkcert в используемой вами операционной системе. Пример для macOS:

    ```bash
    brew install mkcert
    brew install nss # если вы используете Firefox
    ```

2. Добавьте средство mkcert в список локальных корневых центров сертификации.

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

    ```bash
    mkcert -install
    ```

    В результате будет создан локальный центр сертификации (ЦС). Локальный ЦС, созданный средством mkcert, будет доверенным только **локально** на вашем устройстве.

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

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

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

    ```bash
    mkcert localhost
    ```

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

    ```bash
    mkcert mysite.example
    ```

    Приведенная выше команда выполняет две функции:

    - создает сертификат для указанного вами имени хоста;
    - позволяет средству mkcert (которое вы добавили в качестве локального центра сертификации в действии 2) подписать этот сертификат.

    Теперь сертификат готов и подписан центром сертификации, которому ваш браузер доверяет в локальной среде. Почти все сделано, но у вашего сервера еще нет информации об этом сертификате.

4. Настройте сервер.

    Теперь нужно сообщить серверу, что следует использовать протокол HTTPS (так как по умолчанию серверы разработки обычно используют протокол HTTP) и только что созданный сертификат TLS.

    То, как сделать это, зависит от вашего сервера. Ниже приведено несколько примеров.

    **👩🏻‍💻 С использованием узла**

    `server.js` (замените выражения `{ПУТЬ/К/ФАЙЛУ...}` и `{ПОРТ}` нужными значениями):

    ```javascript
    const https = require('https');
    const fs = require('fs');
    const options = {
      key: fs.readFileSync('{ПУТЬ/К/ФАЙЛУ-КЛЮЧА-СЕРТИФИКАТА}.pem'),
      cert: fs.readFileSync('{ПУТЬ/К/ФАЙЛУ-КЛЮЧА-СЕРТИФИКАТА}.pem'),
    };
    https
      .createServer(options, function (req, res) {
        // код сервера
      })
      .listen({ПОРТ});
    ```

    **👩🏻‍💻 С использованием [HTTP-сервера](https://www.npmjs.com/package/http-server)**

    Запустите сервер следующим образом (замените выражение `{ПУТЬ/К/ФАЙЛУ...}` нужным значением):

    ```bash
    http-server -S -C {ПУТЬ/К/ФАЙЛУ-КЛЮЧА-СЕРТИФИКАТА}.pem -K {ПУТЬ/К/ФАЙЛУ-КЛЮЧА-СЕРТИФИКАТА}.pem
    ```

    Параметр `-S` позволяет запустить сервер с использованием протокола HTTPS, параметр `-C` указывает сертификат, а параметр `-K` указывает ключ.

    **👩🏻‍💻 С использованием сервера разработки React**

    Отредактируйте файл `package.json` следующим образом (заменив выражение `{ПУТЬ/К/ФАЙЛУ...}` нужным значением):

    ```json
    "scripts": {
    "start": "HTTPS=true SSL_CRT_FILE={ПУТЬ/К/ФАЙЛУ-КЛЮЧА-СЕРТИФИКАТА}.pem SSL_KEY_FILE={ПУТЬ/К/ФАЙЛУ-КЛЮЧА-СЕРТИФИКАТА}.pem react-scripts start"
    ```

    Например, вы создали сертификат для узла `localhost`, который находится в корневом каталоге сайта, как показано ниже:

    ```text
    |-- my-react-app
        |-- package.json
        |-- localhost.pem
        |-- localhost-key.pem
        |--...
    ```

    Тогда скрипт `start` должен выглядеть следующим образом:

    ```json
    "scripts": {
        "start": "HTTPS=true SSL_CRT_FILE=localhost.pem SSL_KEY_FILE=localhost-key.pem react-scripts start"
    ```

    **👩🏻‍💻 Другие примеры**

    - [Сервер разработки Angular](https://angular.io/cli/serve)
    - [Python](https://blog.anvileight.com/posts/simple-python-http-server/)

5. ✨ Готово! Перейдите на узел `https://localhost` или `https://mysite.example` в браузере: ваш сайт работает в локальной среде с использованием протокола HTTPS. В браузере не будут отображаться никакие предупреждения, потому что он доверяет средству mkcert как локальному центру сертификации.

{% Aside %} На вашем сервере может использоваться другой порт для протокола HTTPS. {% endAside %}

### Использование средства mkcert: шпаргалка

{% Details %} {% DetailsSummary %} Кратко о средстве mkcert {% endDetailsSummary %}

Чтобы запустить локальный сайт разработки с использованием протокола HTTPS, выполните указанные ниже действия.

1. Настройте средство mkcert.

    Установите средство mkcert, если вы еще не сделали этого. Пример для macOS:

    ```bash
    brew install mkcert
    ```

    Ознакомьтесь с инструкциями [по установке средства mkcert](https://github.com/FiloSottile/mkcert#installation) для ОС Windows и Linux.

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

    ```bash
    mkcert -install
    ```

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

    ```bash
    mkcert {ИМЯ ВАШЕГО УЗЛА, например localhost или mysite.example}
    ```

    В результате будет создан действующий сертификат (который будет автоматически подписан средством `mkcert`).

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

4. ✨ Готово! Теперь вы можете открыть сайт `https://{ИМЯ ВАШЕГО УЗЛА}` в браузере и при этом не будут отображаться никакие предупреждения.

{% Aside 'caution' %}

Делайте это только в **целях разработки**. **Никогда не экспортируйте и никому не передавайте** файл `rootCA-key.pem` (если вам нужно узнать, где находится этот файл, чтобы убедиться, что он хранится в безопасном расположении, выполните команду `mkcert -CAROOT`).

{% endAside %}

{% endDetails %}

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

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

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

При таком подходе имеется ряд указанных ниже «подводных камней».

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

<figure>{% Img src="image/admin/KxLz7mcUudiFwWBIdhH8.jpg", alt="Снимки экрана с предупреждениями, отображаемыми браузерами, когда используется самозаверяющий сертификат.", width="800", height="598" %} <figcaption>Предупреждения, отображаемые браузерами, когда используется самозаверяющий сертификат.</figcaption></figure>

{% Aside %} Если вы не укажете никакой сертификат, на основании параметров [React](https://create-react-app.dev/docs/using-https-in-development/) и [Vue](https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve) протокола HTTPS сервера разработки будет автоматически создан самозаверяющий сертификат. Это быстро, но при этом будут отображаться предупреждения браузеров и возникнут другие  перечисленные выше ошибки, связанные с самозаверяющими сертификатами. К счастью, вы можете использовать встроенную опцию HTTPS в интерфейсной части платформы **и** указать локально доверенный сертификат, созданный с помощью mkcert или аналогичного средства. Сведения о том, как сделать это, см. в статье «[Пример mkcert с использованием React](/#setup:~:text=a%20React%20development%20server)». {% endAside %}

{% Details %} {% DetailsSummary %} Почему браузеры не доверяют самозаверяющим сертификатам? {% endDetailsSummary %}

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

<figure>{% Img src="image/admin/V2SAcIzuofqzUuestOOX.jpg", alt="Почему браузеры не доверяют самозаверяющим сертификатам: схема.", width="800", height="833" %} <figcaption>Почему браузеры не доверяют самозаверяющим сертификатам.</figcaption></figure>

{% endDetails %}

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

Вы также можете найти методы, при использовании которого сертификат будет подписан реальным (а не локальным) центром сертификации.

Если вы планируете использовать эти методы, следует помнить о нескольких указанных ниже моментах.

- Вам придется потратить больше усилий на настройку, чем при использовании метода с локальным центром сертификации, например mkcert.
- Вам потребуется использовать допустимое доменное имя, которым вы управляете. Это означает, что вы **не сможете** использовать реальные центры сертификации для:
    - `localhost` и других [зарезервированные](https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml) доменных имен, например `example` или `test`;
    - любых доменных имен, которыми вы не управляете;
    - недопустимых доменов верхнего уровня. См. [список допустимых доменов верхнего уровня](https://www.iana.org/domains/root/db).

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

Еще один способ доступа к сайту, работающему в локальной среде, с помощью протокола HTTPS — использовать [обратный прокси-сервер](https://en.wikipedia.org/wiki/Reverse_proxy), например [ngrok](https://ngrok.com/).

Ниже указано несколько моментов, которые следует учитывать.

- К вашему локальному сайту разработки сможет получить доступ любой человек, которому вы предоставите URL-адрес, созданный с помощью обратного прокси. Это может быть очень удобно при демонстрации проекта клиентам. Но это также может быть недостатком, если вы работаете над конфиденциальным проектом.
- Возможно, вам придется учитывать цены.
- Новые [меры безопасности](/cors-rfc1918-feedback/), применяемые в браузерах, могут влиять на работу этих средств.

### Использование флагов (нерекомендуемый способ)

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

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

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

*Фоновое изображение Hero от пользователя [@anandu](https://unsplash.com/@anandu) с [Unsplash](https://unsplash.com/photos/pbxwxwfI0B4), отредактированное.*
