Skip to content

HTTPS

[Estável: 2 - Estável]

Estável: 2 Estabilidade: 2 - Estável

Código Fonte: lib/https.js

HTTPS é o protocolo HTTP sobre TLS/SSL. No Node.js, isso é implementado como um módulo separado.

Determinando se o suporte a crypto não está disponível

É possível que o Node.js seja construído sem incluir suporte para o módulo node:crypto. Nesses casos, tentar import de https ou chamar require('node:https') resultará em um erro sendo lançado.

Ao usar CommonJS, o erro lançado pode ser capturado usando try/catch:

js
let https
try {
  https = require('node:https')
} catch (err) {
  console.error('o suporte a https está desabilitado!')
}

Ao usar a palavra-chave lexical ESM import, o erro só pode ser capturado se um manipulador para process.on('uncaughtException') for registrado antes de qualquer tentativa de carregar o módulo (usando, por exemplo, um módulo de pré-carregamento).

Ao usar ESM, se houver a possibilidade de o código ser executado em uma versão do Node.js onde o suporte a crypto não está habilitado, considere usar a função import() em vez da palavra-chave lexical import:

js
let https
try {
  https = await import('node:https')
} catch (err) {
  console.error('o suporte a https está desabilitado!')
}

Classe: https.Agent

[Histórico]

VersãoMudanças
v5.3.0suporte a 0 maxCachedSessions para desabilitar o cache de sessão TLS.
v2.5.0parâmetro maxCachedSessions adicionado a options para reutilização de sessões TLS.
v0.4.5Adicionado em: v0.4.5

Um objeto Agent para HTTPS semelhante a http.Agent. Veja https.request() para mais informações.

new Agent([options])

[Histórico]

VersãoMudanças
v12.5.0não definir automaticamente o nome do servidor se o host de destino foi especificado usando um endereço IP.
  • options <Object> Conjunto de opções configuráveis para definir no agente. Pode ter os mesmos campos de http.Agent(options), e
    • maxCachedSessions <number> número máximo de sessões TLS em cache. Use 0 para desabilitar o cache de sessão TLS. Padrão: 100.
    • servername <string> o valor da extensão Server Name Indication a ser enviada para o servidor. Use string vazia '' para desabilitar o envio da extensão. Padrão: nome do host do servidor de destino, a menos que o servidor de destino seja especificado usando um endereço IP, caso em que o padrão é '' (sem extensão). Veja Retomada de Sessão para obter informações sobre a reutilização de sessão TLS.

Evento: 'keylog'

Adicionado em: v13.2.0, v12.16.0

  • line <Buffer> Linha de texto ASCII, no formato SSLKEYLOGFILE do NSS.
  • tlsSocket <tls.TLSSocket> A instância tls.TLSSocket na qual foi gerado.

O evento keylog é emitido quando o material de chave é gerado ou recebido por uma conexão gerenciada por este agente (normalmente antes que o handshake seja concluído, mas não necessariamente). Este material de chave pode ser armazenado para depuração, pois permite que o tráfego TLS capturado seja descriptografado. Ele pode ser emitido várias vezes para cada socket.

Um caso de uso típico é anexar as linhas recebidas a um arquivo de texto comum, que é posteriormente usado por software (como o Wireshark) para descriptografar o tráfego:

js
// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
  fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 })
})

Classe: https.Server

Adicionado em: v0.3.4

Veja http.Server para mais informações.

server.close([callback])

Adicionado em: v0.1.90

Veja server.close() no módulo node:http.

server[Symbol.asyncDispose]()

Adicionado em: v20.4.0

[Estável: 1 - Experimental]

Estável: 1 Estabilidade: 1 - Experimental

Chama server.close() e retorna uma promise que é cumprida quando o servidor é fechado.

server.closeAllConnections()

Adicionado em: v18.2.0

Veja server.closeAllConnections() no módulo node:http.

server.closeIdleConnections()

Adicionado em: v18.2.0

Veja server.closeIdleConnections() no módulo node:http.

server.headersTimeout

Adicionado em: v11.3.0

Consulte server.headersTimeout no módulo node:http.

server.listen()

Inicia o servidor HTTPS ouvindo por conexões criptografadas. Este método é idêntico a server.listen() de net.Server.

server.maxHeadersCount

Consulte server.maxHeadersCount no módulo node:http.

server.requestTimeout

[Histórico]

VersãoMudanças
v18.0.0O tempo limite de solicitação padrão mudou de sem tempo limite para 300s (5 minutos).
v14.11.0Adicionado em: v14.11.0

Consulte server.requestTimeout no módulo node:http.

server.setTimeout([msecs][, callback])

Adicionado em: v0.11.2

Consulte server.setTimeout() no módulo node:http.

server.timeout

[Histórico]

VersãoMudanças
v13.0.0O tempo limite padrão mudou de 120s para 0 (sem tempo limite).
v0.11.2Adicionado em: v0.11.2

Consulte server.timeout no módulo node:http.

server.keepAliveTimeout

Adicionado em: v8.0.0

Veja server.keepAliveTimeout no módulo node:http.

https.createServer([options][, requestListener])

Adicionado em: v0.3.4

js
// curl -k https://localhost:8000/
import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const options = {
  key: readFileSync('private-key.pem'),
  cert: readFileSync('certificate.pem'),
}

createServer(options, (req, res) => {
  res.writeHead(200)
  res.end('hello world\n')
}).listen(8000)
js
// curl -k https://localhost:8000/
const https = require('node:https')
const fs = require('node:fs')

const options = {
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
}

https
  .createServer(options, (req, res) => {
    res.writeHead(200)
    res.end('hello world\n')
  })
  .listen(8000)

Ou

js
import { createServer } from 'node:https'
import { readFileSync } from 'node:fs'

const options = {
  pfx: readFileSync('test_cert.pfx'),
  passphrase: 'sample',
}

createServer(options, (req, res) => {
  res.writeHead(200)
  res.end('hello world\n')
}).listen(8000)
js
const https = require('node:https')
const fs = require('node:fs')

const options = {
  pfx: fs.readFileSync('test_cert.pfx'),
  passphrase: 'sample',
}

https
  .createServer(options, (req, res) => {
    res.writeHead(200)
    res.end('hello world\n')
  })
  .listen(8000)

Para gerar o certificado e a chave para este exemplo, execute:

bash
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
  -keyout private-key.pem -out certificate.pem

Em seguida, para gerar o certificado pfx para este exemplo, execute:

bash
openssl pkcs12 -certpbe AES-256-CBC -export -out test_cert.pfx \
  -inkey private-key.pem -in certificate.pem -passout pass:sample

https.get(options[, callback])

https.get(url[, options][, callback])

[Histórico]

VersãoMudanças
v10.9.0O parâmetro url agora pode ser passado juntamente com um objeto options separado.
v7.5.0O parâmetro options pode ser um objeto URL WHATWG.
v0.3.6Adicionado em: v0.3.6

Como http.get() mas para HTTPS.

options pode ser um objeto, uma string ou um objeto URL. Se options for uma string, ela é automaticamente analisada com new URL(). Se for um objeto URL, ele será automaticamente convertido em um objeto options comum.

js
import { get } from 'node:https'
import process from 'node:process'

get('https://encrypted.google.com/', res => {
  console.log('statusCode:', res.statusCode)
  console.log('headers:', res.headers)

  res.on('data', d => {
    process.stdout.write(d)
  })
}).on('error', e => {
  console.error(e)
})
js
const https = require('node:https')

https
  .get('https://encrypted.google.com/', res => {
    console.log('statusCode:', res.statusCode)
    console.log('headers:', res.headers)

    res.on('data', d => {
      process.stdout.write(d)
    })
  })
  .on('error', e => {
    console.error(e)
  })

https.globalAgent

[Histórico]

VersãoMudanças
v19.0.0O agente agora usa HTTP Keep-Alive e um tempo limite de 5 segundos por padrão.
v0.5.9Adicionado em: v0.5.9

Instância global de https.Agent para todas as requisições de clientes HTTPS. Difere de uma configuração padrão https.Agent por ter keepAlive habilitado e um timeout de 5 segundos.

https.request(options[, callback])

https.request(url[, options][, callback])

[Histórico]

VersãoMudanças
v22.4.0, v20.16.0A opção clientCertEngine depende do suporte de mecanismo personalizado no OpenSSL, que está depreciado no OpenSSL 3.
v16.7.0, v14.18.0Ao usar um objeto URL, o nome de usuário e a senha analisados agora serão devidamente decodificados por URI.
v14.1.0, v13.14.0A opção highWaterMark agora é aceita.
v10.9.0O parâmetro url agora pode ser passado junto com um objeto options separado.
v9.3.0O parâmetro options agora pode incluir clientCertEngine.
v7.5.0O parâmetro options pode ser um objeto WHATWG URL.
v0.3.6Adicionado em: v0.3.6

Faz uma requisição a um servidor web seguro.

As seguintes options adicionais de tls.connect() também são aceitas: ca, cert, ciphers, clientCertEngine (depreciado), crl, dhparam, ecdhCurve, honorCipherOrder, key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext, highWaterMark.

options pode ser um objeto, uma string ou um objeto URL. Se options for uma string, ela é analisada automaticamente com new URL(). Se for um objeto URL, ele será convertido automaticamente em um objeto options comum.

https.request() retorna uma instância da classe http.ClientRequest. A instância ClientRequest é um fluxo gravável. Se for necessário carregar um arquivo com uma requisição POST, grave no objeto ClientRequest.

js
import { request } from 'node:https'
import process from 'node:process'

const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
}

const req = request(options, res => {
  console.log('statusCode:', res.statusCode)
  console.log('headers:', res.headers)

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', e => {
  console.error(e)
})
req.end()
js
const https = require('node:https')

const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
}

const req = https.request(options, res => {
  console.log('statusCode:', res.statusCode)
  console.log('headers:', res.headers)

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', e => {
  console.error(e)
})
req.end()

Exemplo usando opções de tls.connect():

js
const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
}
options.agent = new https.Agent(options)

const req = https.request(options, res => {
  // ...
})

Alternativamente, opte por não usar o agrupamento de conexões não usando um Agent.

js
const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
  agent: false,
}

const req = https.request(options, res => {
  // ...
})

Exemplo usando uma URL como options:

js
const options = new URL('https://abc:')

const req = https.request(options, res => {
  // ...
})

Exemplo de fixação na impressão digital do certificado ou na chave pública (semelhante a pin-sha256):

js
import { checkServerIdentity } from 'node:tls'
import { Agent, request } from 'node:https'
import { createHash } from 'node:crypto'

function sha256(s) {
  return createHash('sha256').update(s).digest('base64')
}
const options = {
  hostname: 'github.com',
  port: 443,
  path: '/',
  method: 'GET',
  checkServerIdentity: function (host, cert) {
    // Certifique-se de que o certificado seja emitido para o host ao qual estamos conectados
    const err = checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // Fixe a chave pública, semelhante à fixação HPKP pin-sha256
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'Erro de verificação de certificado: ' +
        `A chave pública de '${cert.subject.CN}' ` +
        'não corresponde à nossa impressão digital fixada'
      return new Error(msg)
    }

    // Fixe o certificado exato, em vez da chave pública
    const cert256 =
      'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' + '0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65'
    if (cert.fingerprint256 !== cert256) {
      const msg =
        'Erro de verificação de certificado: ' +
        `O certificado de '${cert.subject.CN}' ` +
        'não corresponde à nossa impressão digital fixada'
      return new Error(msg)
    }

    // Este loop é apenas informativo.
    // Imprima as impressões digitais do certificado e da chave pública de todos os certificados na
    // cadeia. É comum fixar a chave pública do emissor na Internet pública, enquanto fixa a chave pública do serviço em ambientes confidenciais.
    let lastprint256
    do {
      console.log('Nome Comum do Assunto:', cert.subject.CN)
      console.log('  Impressão Digital SHA256 do Certificado:', cert.fingerprint256)

      const hash = createHash('sha256')
      console.log('  Chave pública ping-sha256:', sha256(cert.pubkey))

      lastprint256 = cert.fingerprint256
      cert = cert.issuerCertificate
    } while (cert.fingerprint256 !== lastprint256)
  },
}

options.agent = new Agent(options)
const req = request(options, res => {
  console.log('Tudo OK. O servidor correspondeu ao nosso certificado ou chave pública fixada')
  console.log('statusCode:', res.statusCode)

  res.on('data', d => {})
})

req.on('error', e => {
  console.error(e.message)
})
req.end()
js
const tls = require('node:tls')
const https = require('node:https')
const crypto = require('node:crypto')

function sha256(s) {
  return crypto.createHash('sha256').update(s).digest('base64')
}
const options = {
  hostname: 'github.com',
  port: 443,
  path: '/',
  method: 'GET',
  checkServerIdentity: function (host, cert) {
    // Certifique-se de que o certificado seja emitido para o host ao qual estamos conectados
    const err = tls.checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // Fixe a chave pública, semelhante à fixação HPKP pin-sha256
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'Erro de verificação de certificado: ' +
        `A chave pública de '${cert.subject.CN}' ` +
        'não corresponde à nossa impressão digital fixada'
      return new Error(msg)
    }

    // Fixe o certificado exato, em vez da chave pública
    const cert256 =
      'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' + '0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65'
    if (cert.fingerprint256 !== cert256) {
      const msg =
        'Erro de verificação de certificado: ' +
        `O certificado de '${cert.subject.CN}' ` +
        'não corresponde à nossa impressão digital fixada'
      return new Error(msg)
    }

    // Este loop é apenas informativo.
    // Imprima as impressões digitais do certificado e da chave pública de todos os certificados na
    // cadeia. É comum fixar a chave pública do emissor na Internet pública, enquanto fixa a chave pública do serviço em ambientes confidenciais.
    do {
      console.log('Nome Comum do Assunto:', cert.subject.CN)
      console.log('  Impressão Digital SHA256 do Certificado:', cert.fingerprint256)

      hash = crypto.createHash('sha256')
      console.log('  Chave pública ping-sha256:', sha256(cert.pubkey))

      lastprint256 = cert.fingerprint256
      cert = cert.issuerCertificate
    } while (cert.fingerprint256 !== lastprint256)
  },
}

options.agent = new https.Agent(options)
const req = https.request(options, res => {
  console.log('Tudo OK. O servidor correspondeu ao nosso certificado ou chave pública fixada')
  console.log('statusCode:', res.statusCode)

  res.on('data', d => {})
})

req.on('error', e => {
  console.error(e.message)
})
req.end()

Saídas por exemplo:

text
Nome Comum do Assunto: github.com
  Impressão Digital SHA256 do Certificado: FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65
  Chave pública ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
Nome Comum do Assunto: Sectigo ECC Domain Validation Secure Server CA
  Impressão Digital SHA256 do Certificado: 61:E9:73:75:E9:F6:DA:98:2F:F5:C1:9E:2F:94:E6:6C:4E:35:B6:83:7C:E3:B9:14:D2:24:5C:7F:5F:65:82:5F
  Chave pública ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
Nome Comum do Assunto: USERTrust ECC Certification Authority
  Impressão Digital SHA256 do Certificado: A6:CF:64:DB:B4:C8:D5:FD:19:CE:48:89:60:68:DB:03:B5:33:A8:D1:33:6C:62:56:A8:7D:00:CB:B3:DE:F3:EA
  Chave pública ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
Nome Comum do Assunto: AAA Certificate Services
  Impressão Digital SHA256 do Certificado: D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
  Chave pública ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
Tudo OK. O servidor correspondeu ao nosso certificado ou chave pública fixada
statusCode: 200