Usar HTTPS para desenvolvimento local

Maud Nalpas
Maud Nalpas

Na maioria das vezes, o http://localhost se comporta como HTTPS para fins de desenvolvimento. No entanto, há alguns casos especiais, como nomes de host personalizados ou o uso de cookies seguros em vários navegadores, em que você precisa configurar explicitamente o site de desenvolvimento para que ele se comporte como HTTPS para representar com precisão como o site funciona na produção. Se o site de produção não usar HTTPS, priorize a mudança para HTTPS.

Esta página explica como executar seu site localmente com HTTPS.

Para instruções breves, consulte a referência rápida de mkcert.**

Executar seu site localmente com HTTPS usando o mkcert (recomendado)

Para usar o HTTPS com seu site de desenvolvimento local e acessar https://localhost ou https://mysite.example (nome de host personalizado), você precisa de um certificado TLS assinado por uma entidade confiável para o dispositivo e o navegador, chamada de autoridade de certificação (CA, na sigla em inglês) confiável. O navegador verifica se o certificado do servidor de desenvolvimento está assinado por uma AC confiável antes de criar uma conexão HTTPS.

Recomendamos o uso de mkcert, uma AC multiplataforma, para criar e assinar seu certificado. Para outras opções úteis, consulte Executar seu site localmente com HTTPS: outras opções.

Muitos sistemas operacionais incluem bibliotecas para criar certificados, como openssl. No entanto, elas são mais complexas e menos confiáveis do que o mkcert e não são necessariamente multiplataforma, o que as torna menos acessíveis para equipes de desenvolvedores maiores.

Configuração

  1. Instale o mkcert (somente uma vez).

    Siga as instruções para instalar o mkcert no seu sistema operacional. Por exemplo, no macOS:

    brew install mkcert
    brew install nss # if you use Firefox
    
  2. Adicione mkcert às ACs raiz locais.

    No terminal, execute o seguinte comando:

    mkcert -install
    

    Isso gera uma autoridade certificadora (AC) local. A AC local gerada pelo mkcert só é confiável localmente, no seu dispositivo.

  3. Gere um certificado para seu site, assinado por mkcert.

    No seu terminal, navegue até o diretório raiz do site ou qualquer diretório em que você queira manter seu certificado.

    Depois, execute:

    mkcert localhost
    

    Se você estiver usando um nome de host personalizado, como mysite.example, execute:

    mkcert mysite.example
    

    Esse comando faz duas coisas:

    • Gera um certificado para o nome do host especificado.
    • Permite que o mkcert assine o certificado.

    Seu certificado está pronto e assinado por uma autoridade de certificação confiável pelo seu navegador localmente.

  4. Configure o servidor para usar o HTTPS com o certificado TLS que você acabou de criar.

    Os detalhes de como fazer isso dependem do seu servidor. Confira alguns exemplos:

    👩🏻‍💻 Com o nó:

    server.js (substitua {PATH/TO/CERTIFICATE...} e {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});
    

    👩🏻 💻 Com http-server:

    Inicie o servidor da seguinte forma (substitua {PATH/TO/CERTIFICATE...}):

    http-server -S -C {PATH/TO/CERTIFICATE-FILENAME}.pem -K {PATH/TO/CERTIFICATE-KEY-FILENAME}.pem
    

    -S executa o servidor com HTTPS, enquanto -C define o certificado e -K define a chave.

    👩🏻 💻 Com um servidor de desenvolvimento do React:

    Edite o package.json da seguinte maneira e substitua {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"
    

    Por exemplo, se você criou um certificado para localhost no diretório raiz do site:

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

    Seu script start ficará assim:

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

    👩🏻‍💻 Outros exemplos:

  5. Abra https://localhost ou https://mysite.example no navegador para verificar se o site está sendo executado localmente com HTTPS. Nenhum aviso do navegador será exibido, porque o navegador confia no mkcert como uma autoridade de certificado local.

Referência rápida do mkcert

Para executar o site de desenvolvimento local com HTTPS:

  1. Configure o mkcert.

    Instale o mkcert, por exemplo, no macOS:

    brew install mkcert

    Consulte install mkcert para instruções para Windows e Linux.

    Em seguida, crie uma autoridade certificadora local:

    mkcert -install
  2. Crie um certificado confiável.

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

    Isso cria um certificado válido que o mkcert assina automaticamente.

  3. Configure o servidor de desenvolvimento para usar HTTPS e o certificado criado na Etapa 2.

Agora é possível acessar https://{YOUR HOSTNAME} no navegador sem avisos

</div>

Executar seu site localmente com HTTPS: outras opções

Confira a seguir outras maneiras de configurar seu certificado. Geralmente, eles são mais complicados ou arriscados do que usar o mkcert.

Certificado autoassinado

Você também pode optar por não usar uma autoridade certificadora local, como mkcert, e assinar o certificado por conta própria. Essa abordagem tem algumas armadilhas:

  • Os navegadores não confiam em você como autoridade de certificação, por isso mostram avisos que você precisa ignorar manualmente. No Chrome, é possível usar a flag #allow-insecure-localhost para ignorar esse aviso automaticamente no localhost.
  • Isso não é seguro se você estiver trabalhando em uma rede não segura.
  • Não é necessariamente mais fácil ou rápido do que usar uma AC local, como mkcert.
  • Os certificados autoassinados não se comportam exatamente da mesma forma que os certificados confiáveis.
  • Se você não estiver usando essa técnica em um contexto de navegador, desative a verificação de certificado do servidor. Esquecer de reativá-lo na produção causa problemas de segurança.
Capturas de tela dos avisos que os navegadores mostram quando um certificado autoassinado é usado.
Os avisos dos navegadores são exibidos quando um certificado autoassinado é usado.

Se você não especificar um certificado, as opções HTTPS do servidor de desenvolvimento do React e do Vue criam um certificado autoassinado em segundo plano. Isso é rápido, mas vem com os mesmos avisos do navegador e outras armadilhas de certificados autoassinados. Felizmente, é possível usar a opção HTTPS integrada de frameworks de front-end e especificar um certificado de confiança local criado usando mkcert ou algo semelhante. Para mais informações, consulte o exemplo mkcert com React.

Se você abrir o site em execução localmente no navegador usando HTTPS, ele verificará o certificado do servidor de desenvolvimento local. Quando ele verifica que você assinou o certificado, ele verifica se você está registrado como uma autoridade certificadora confiável. Como você não tem, o navegador não pode confiar no certificado e mostra um aviso informando que a conexão não é segura. Se você continuar, ele ainda criará a conexão HTTPS, mas você fará isso por sua conta e risco.

Por que os navegadores não confiam em certificados autoassinados: um diagrama.
Por que os navegadores não confiam em certificados autoassinados.

Certificado assinado por uma autoridade certificadora comum

Também é possível usar um certificado assinado por uma AC oficial. Isso traz as seguintes complicações:

  • Você tem mais trabalho de configuração do que ao usar uma técnica de AC local, como mkcert.
  • Você precisa usar um nome de domínio válido que você controla. Isso significa que não é possível usar ACs oficiais para:

Proxy reverso

Outra opção para acessar um site em execução localmente com HTTPS é usar um proxy reverso, como o ngrok. Isso traz os seguintes riscos:

  • Qualquer pessoa com quem você compartilhar o URL do proxy reverso pode acessar seu site de desenvolvimento local. Isso pode ser útil para demonstrar seu projeto aos clientes, mas também permite que pessoas não autorizadas compartilhem informações confidenciais.
  • Alguns serviços de proxy reverso cobram pelo uso, portanto, o preço pode ser um fator na sua escolha de serviço.
  • Novas medidas de segurança nos navegadores podem afetar o funcionamento dessas ferramentas.

Se você estiver usando um nome de host personalizado, como mysite.example, no Chrome, use uma flag para forçar o navegador a considerar mysite.example como seguro. Evite fazer isso pelos seguintes motivos:

  • Você precisa ter certeza total de que mysite.example sempre resolve para um endereço local. Caso contrário, você corre o risco de vazar credenciais de produção.
  • Essa flag só funciona no Chrome, então não é possível depurar em vários navegadores.

Agradecemos as contribuições e o feedback de todos os revisores e colaboradores, especialmente Ryan Sleevi, Filippo Valsorda, Milica Mihajlija e Rowan Merewood. 🙌

Plano de fundo da imagem principal de @anandu no Unsplash, editado.