Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

HTTPS e TLS no Node.js: Guia Prático

Atualizado em: 1 de agosto de 2026

Cadeado ilustrando Crypto no Node.js

HTTPS protege a comunicação entre cliente e servidor usando TLS. Em uma aplicação Node.js, ele evita que terceiros leiam ou alterem credenciais, cookies, payloads e respostas durante o transporte. Os módulos nativos node:https e node:tls permitem criar servidores, clientes e conexões autenticadas sem bibliotecas externas.

Configurar HTTPS não se resume a carregar um certificado. É necessário validar cadeias de confiança, escolher protocolos modernos, renovar certificados, aplicar timeouts e decidir onde o TLS termina. Em muitas arquiteturas, um proxy ou load balancer recebe a conexão segura e encaminha tráfego para o Node.js.

Neste guia, você aprenderá a criar servidor HTTPS, configurar certificados, usar SNI, validar clientes, implementar mTLS, fazer requisições seguras e organizar rotação e observabilidade.

HTTPS e TLS: qual é a diferença?

TLS é o protocolo que autentica participantes e cria um canal criptografado. HTTPS é HTTP transportado sobre TLS. A conexão começa com um handshake que negocia versão, algoritmo e chaves, além de validar o certificado apresentado pelo servidor.

A documentação oficial de HTTPS e a documentação oficial de TLS detalham opções e eventos.

Para revisar servidores, consulte o que é Node.js e como criar uma API com Node.js.

Criando um servidor HTTPS

const https = require('node:https');
const fs = require('node:fs');

const server = https.createServer({
  key: fs.readFileSync('./certs/private-key.pem'),
  cert: fs.readFileSync('./certs/certificate.pem')
}, (req, res) => {
  res.writeHead(200, {
    'content-type': 'application/json'
  });

  res.end(JSON.stringify({ secure: true }));
});

server.listen(443);

Leituras síncronas podem ser aceitáveis durante a inicialização, antes de o servidor aceitar requisições. Durante o atendimento, prefira APIs assíncronas para não bloquear o event loop.

Certificado e chave privada

O certificado contém a chave pública e informações sobre o domínio. A chave privada prova que o servidor controla o certificado e nunca deve ser exposta. A cadeia intermediária também pode precisar ser enviada:

const options = {
  key: fs.readFileSync('./certs/key.pem'),
  cert: fs.readFileSync('./certs/cert.pem'),
  ca: fs.readFileSync('./certs/chain.pem')
};

Proteja a chave com permissões restritas ou serviço de segredos. Não a inclua em Git, imagem de contêiner ou logs.

Certificados locais

Em desenvolvimento, use uma autoridade local confiável ou ferramenta que instale um certificado de teste. Desativar validação globalmente ensina o código a aceitar ataques intermediários e pode chegar acidentalmente à produção.

Fazendo uma requisição HTTPS

const https = require('node:https');

const request = https.get(
  'https://api.example.com/status',
  response => {
    const chunks = [];

    response.on('data', chunk => chunks.push(chunk));
    response.on('end', () => {
      console.log(Buffer.concat(chunks).toString('utf8'));
    });
  }
);

request.on('error', console.error);

Para respostas grandes, processe por stream. Veja Streams no Node.js.

Não desative rejectUnauthorized

https.get(url, {
  rejectUnauthorized: false
});

Essa opção aceita qualquer certificado e elimina a autenticação do servidor. Use apenas em diagnóstico local controlado. Em produção, forneça a CA correta ou corrija a cadeia.

Autoridade certificadora privada

const agent = new https.Agent({
  ca: fs.readFileSync('./certs/internal-ca.pem'),
  keepAlive: true
});

https.get('https://internal.example', { agent }, response => {
  // consumir resposta
});

Ao definir ca, confirme se você deseja substituir ou complementar as autoridades padrão.

Reutilizando conexões

Um https.Agent com keep-alive reduz handshakes e latência:

const agent = new https.Agent({
  keepAlive: true,
  maxSockets: 100,
  maxFreeSockets: 20,
  timeout: 30_000
});

Limite sockets para evitar sobrecarga e feche o agent durante o desligamento.

Timeouts

const req = https.request(options, response => {
  // processar resposta
});

req.setTimeout(5000, () => {
  req.destroy(new Error('Tempo limite excedido'));
});

Timeout de conexão, headers e corpo podem precisar de políticas diferentes. Combine com AbortController no Node.js.

SNI e vários domínios

Server Name Indication permite selecionar certificado conforme o hostname solicitado:

const tls = require('node:tls');

const contexts = {
  'api.example.com': tls.createSecureContext({ key, cert }),
  'admin.example.com': tls.createSecureContext({
    key: adminKey,
    cert: adminCert
  })
};

const server = https.createServer({
  SNICallback(servername, callback) {
    callback(null, contexts[servername]);
  }
});

Valide o hostname e tenha um contexto padrão seguro.

mTLS

No TLS mútuo, o cliente também apresenta certificado. Isso é útil em integrações internas, parceiros e dispositivos:

const server = https.createServer({
  key,
  cert,
  ca: clientCa,
  requestCert: true,
  rejectUnauthorized: true
}, (req, res) => {
  const certificate = req.socket.getPeerCertificate();
  res.end(JSON.stringify({ subject: certificate.subject }));
});

Não autorize apenas porque o certificado é válido. Verifique identidade, emissor, uso de chave, revogação e permissões do serviço.

Cliente mTLS

const agent = new https.Agent({
  key: clientKey,
  cert: clientCert,
  ca: serverCa,
  keepAlive: true
});

Distribuição e rotação de certificados de cliente precisam de inventário e automação.

Versões e cifras

Prefira TLS 1.2 ou 1.3, conforme requisitos do ambiente:

const server = https.createServer({
  key,
  cert,
  minVersion: 'TLSv1.2'
});

Evite listas manuais de cifras sem necessidade. Atualize Node.js e OpenSSL para receber correções e padrões modernos.

Proxy reverso

Quando Nginx, CDN ou load balancer termina TLS, o Node.js pode receber HTTP interno. Proteja esse trecho em redes não confiáveis e configure corretamente cabeçalhos de proxy. Não aceite X-Forwarded-Proto de qualquer origem.

Para HTTP/2, veja HTTP/2 no Node.js.

HSTS

O cabeçalho Strict-Transport-Security instrui o navegador a usar HTTPS:

res.setHeader(
  'strict-transport-security',
  'max-age=31536000; includeSubDomains'
);

Ative somente quando todos os subdomínios estiverem preparados. Uma configuração incorreta pode bloquear acesso HTTP necessário.

Rotação de certificados

Automatize emissão e renovação. Monitore data de expiração e teste a cadeia. Em serviços que carregam arquivos apenas na inicialização, reinicie de forma gradual após a renovação. Algumas arquiteturas permitem trocar o contexto seguro sem interromper conexões existentes.

Encerramento gradual

Pare novas conexões, aguarde requisições e destrua sockets remanescentes após um limite. Acompanhe agents e conexões keep-alive para o processo não permanecer aberto.

Observabilidade

Monitore falhas de handshake, versão negociada, expiração, tempo de conexão e erros como CERT_HAS_EXPIRED ou UNABLE_TO_VERIFY_LEAF_SIGNATURE. Não registre chaves privadas nem certificados completos de clientes sem necessidade.

Testando

Teste certificado válido, expirado, hostname incorreto, CA privada, cliente sem certificado, rotação e fallback. Use ferramentas como OpenSSL para inspecionar a cadeia e ALPN, mas valide também com o cliente real.

Erros comuns

  • Desativar validação de certificado em produção.
  • Guardar chave privada no repositório.
  • Esquecer certificados intermediários.
  • Não definir timeout e limite de sockets.
  • Autorizar cliente mTLS apenas pelo CN.
  • Confiar em cabeçalhos de proxy não validados.
  • Renovar certificado sem recarregar o serviço.
  • Permitir versões antigas de TLS.

Boas práticas

  • Use TLS 1.2 ou superior.
  • Automatize emissão, renovação e alerta de expiração.
  • Proteja chaves com controle de acesso.
  • Reutilize conexões com limites.
  • Defina timeouts em servidor e cliente.
  • Valide cadeia, hostname e finalidade.
  • Planeje rotação de mTLS.
  • Teste através do proxy real.
  • Implemente encerramento gradual.
  • Mantenha Node.js atualizado.

Conclusão

HTTPS e TLS no Node.js protegem dados em trânsito e autenticam serviços. Os módulos nativos permitem criar servidores seguros, clientes com CA privada e comunicação mTLS.

A proteção depende da operação contínua: validar certificados, limitar conexões, renovar chaves e monitorar falhas. Com configuração moderna e automação, o TLS se torna uma camada previsível da arquitetura, não uma tarefa manual próxima da expiração.

Os 10 Melhores Cursos de Programação de 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita