HTTPS
[Estable: 2 - Estable]
Estable: 2 Estabilidad: 2 - Estable
Código fuente: lib/https.js
HTTPS es el protocolo HTTP sobre TLS/SSL. En Node.js, esto se implementa como un módulo separado.
Determinar si el soporte de crypto no está disponible
Es posible que Node.js se construya sin incluir soporte para el módulo node:crypto
. En tales casos, intentar import
desde https
o llamar a require('node:https')
resultará en un error.
Cuando se usa CommonJS, el error lanzado se puede capturar usando try/catch:
let https
try {
https = require('node:https')
} catch (err) {
console.error('¡El soporte de https está deshabilitado!')
}
Cuando se usa la palabra clave léxica ESM import
, el error solo se puede capturar si se registra un controlador para process.on('uncaughtException')
antes de que se realice cualquier intento de cargar el módulo (usando, por ejemplo, un módulo de precarga).
Cuando se usa ESM, si existe la posibilidad de que el código se ejecute en una compilación de Node.js donde el soporte de crypto no esté habilitado, considere usar la función import()
en lugar de la palabra clave léxica import
:
let https
try {
https = await import('node:https')
} catch (err) {
console.error('¡El soporte de https está deshabilitado!')
}
Clase: https.Agent
[Historial]
Versión | Cambios |
---|---|
v5.3.0 | Soporte para 0 maxCachedSessions para deshabilitar el almacenamiento en caché de sesiones TLS. |
v2.5.0 | Se agregó el parámetro maxCachedSessions a options para la reutilización de sesiones TLS. |
v0.4.5 | Agregado en: v0.4.5 |
Un objeto Agent
para HTTPS similar a http.Agent
. Consulte https.request()
para obtener más información.
new Agent([options])
[Historial]
Versión | Cambios |
---|---|
v12.5.0 | No establece automáticamente el nombre del servidor si el host de destino se especificó mediante una dirección IP. |
options
<Object> Conjunto de opciones configurables para establecer en el agente. Puede tener los mismos campos que parahttp.Agent(options)
, ymaxCachedSessions
<number> número máximo de sesiones TLS almacenadas en caché. Use0
para deshabilitar el almacenamiento en caché de sesiones TLS. Predeterminado:100
.servername
<string> el valor de la extensión de Indicación de Nombre de Servidor que se enviará al servidor. Use una cadena vacía''
para deshabilitar el envío de la extensión. Predeterminado: nombre de host del servidor de destino, a menos que el servidor de destino se especifique mediante una dirección IP, en cuyo caso el valor predeterminado es''
(sin extensión). ConsulteReanudación de Sesión
para obtener información sobre la reutilización de sesiones TLS.
Evento: 'keylog'
Agregado en: v13.2.0, v12.16.0
line
<Buffer> Línea de texto ASCII, en formato NSSSSLKEYLOGFILE
.tlsSocket
<tls.TLSSocket> La instanciatls.TLSSocket
en la que se generó.
El evento keylog
se emite cuando un material de clave es generado o recibido por una conexión gestionada por este agente (normalmente antes de que se complete el handshake, pero no necesariamente). Este material de clave se puede almacenar para depuración, ya que permite descifrar el tráfico TLS capturado. Se puede emitir varias veces para cada socket.
Un caso de uso típico es añadir las líneas recibidas a un archivo de texto común, que luego es utilizado por un software (como Wireshark) para descifrar el tráfico:
// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 })
})
Clase: https.Server
Agregado en: v0.3.4
- Extiende: <tls.Server>
Ver http.Server
para más información.
server.close([callback])
Agregado en: v0.1.90
callback
<Function>- Devuelve: <https.Server>
Ver server.close()
en el módulo node:http
.
server[Symbol.asyncDispose]()
Agregado en: v20.4.0
[Estable: 1 - Experimental]
Estable: 1 Estabilidad: 1 - Experimental
Llama a server.close()
y devuelve una promesa que se cumple cuando el servidor se ha cerrado.
server.closeAllConnections()
Agregado en: v18.2.0
Ver server.closeAllConnections()
en el módulo node:http
.
server.closeIdleConnections()
Agregado en: v18.2.0
Ver server.closeIdleConnections()
en el módulo node:http
.
server.headersTimeout
Agregado en: v11.3.0
- <number> Predeterminado:
60000
Ver server.headersTimeout
en el módulo node:http
.
server.listen()
Comienza el servidor HTTPS a escuchar conexiones encriptadas. Este método es idéntico a server.listen()
de net.Server
.
server.maxHeadersCount
- <number> Predeterminado:
2000
Ver server.maxHeadersCount
en el módulo node:http
.
server.requestTimeout
[Historial]
Versión | Cambios |
---|---|
v18.0.0 | El tiempo de espera predeterminado de la solicitud cambió de sin tiempo de espera a 300 segundos (5 minutos). |
v14.11.0 | Añadido en: v14.11.0 |
- <number> Predeterminado:
300000
Ver server.requestTimeout
en el módulo node:http
.
server.setTimeout([msecs][, callback])
Añadido en: v0.11.2
msecs
<number> Predeterminado:120000
(2 minutos)callback
<Function>- Devuelve: <https.Server>
Ver server.setTimeout()
en el módulo node:http
.
server.timeout
[Historial]
Versión | Cambios |
---|---|
v13.0.0 | El tiempo de espera predeterminado cambió de 120s a 0 (sin tiempo de espera). |
v0.11.2 | Agregado en: v0.11.2 |
- <number> Predeterminado: 0 (sin tiempo de espera)
Ver server.timeout
en el módulo node:http
.
server.keepAliveTimeout
Agregado en: v8.0.0
- <number> Predeterminado:
5000
(5 segundos)
Ver server.keepAliveTimeout
en el módulo node:http
.
https.createServer([options][, requestListener])
Agregado en: v0.3.4
options
<Object> Aceptaoptions
detls.createServer()
,tls.createSecureContext()
yhttp.createServer()
.requestListener
<Function> Un listener para ser añadido al evento'request'
.- Retorna: <https.Server>
// 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)
// 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)
O
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)
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 generar el certificado y la clave para este ejemplo, ejecute:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout private-key.pem -out certificate.pem
Luego, para generar el certificado pfx
para este ejemplo, ejecute:
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])
[Historial]
Versión | Cambios |
---|---|
v10.9.0 | El parámetro url ahora se puede pasar junto con un objeto options separado. |
v7.5.0 | El parámetro options puede ser un objeto WHATWG URL . |
v0.3.6 | Añadido en: v0.3.6 |
url
<string> | <URL>options
<Object> | <string> | <URL> Acepta las mismasoptions
quehttps.request()
, con el método establecido en GET de forma predeterminada.callback
<Function>
Similar a http.get()
pero para HTTPS.
options
puede ser un objeto, una cadena o un objeto URL
. Si options
es una cadena, se analiza automáticamente con new URL()
. Si es un objeto URL
, se convertirá automáticamente en un objeto options
ordinario.
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)
})
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
[Historial]
Versión | Cambios |
---|---|
v19.0.0 | El agente ahora utiliza HTTP Keep-Alive y un tiempo de espera de 5 segundos por defecto. |
v0.5.9 | Añadido en: v0.5.9 |
Instancia global de https.Agent
para todas las solicitudes de cliente HTTPS. Difiere de una configuración predeterminada de https.Agent
al tener keepAlive
habilitado y un timeout
de 5 segundos.
https.request(options[, callback])
https.request(url[, options][, callback])
[Historial]
Versión | Cambios |
---|---|
v22.4.0, v20.16.0 | La opción clientCertEngine depende del soporte del motor personalizado en OpenSSL que está en desuso en OpenSSL 3. |
v16.7.0, v14.18.0 | Al usar un objeto URL , el nombre de usuario y la contraseña analizados ahora se decodificarán URI correctamente. |
v14.1.0, v13.14.0 | Ahora se acepta la opción highWaterMark . |
v10.9.0 | El parámetro url ahora se puede pasar junto con un objeto options separado. |
v9.3.0 | El parámetro options ahora puede incluir clientCertEngine . |
v7.5.0 | El parámetro options puede ser un objeto URL WHATWG. |
v0.3.6 | Añadido en: v0.3.6 |
url
<string> | <URL>options
<Object> | <string> | <URL> Acepta todas lasoptions
dehttp.request()
, con algunas diferencias en los valores predeterminados:protocol
Predeterminado:'https:'
port
Predeterminado:443
agent
Predeterminado:https.globalAgent
callback
<Function>- Devuelve: <http.ClientRequest>
Realiza una solicitud a un servidor web seguro.
También se aceptan las siguientes options
adicionales de tls.connect()
: ca
, cert
, ciphers
, clientCertEngine
(obsoleto), crl
, dhparam
, ecdhCurve
, honorCipherOrder
, key
, passphrase
, pfx
, rejectUnauthorized
, secureOptions
, secureProtocol
, servername
, sessionIdContext
, highWaterMark
.
options
puede ser un objeto, una cadena o un objeto URL
. Si options
es una cadena, se analiza automáticamente con new URL()
. Si es un objeto URL
, se convertirá automáticamente en un objeto options
ordinario.
https.request()
devuelve una instancia de la clase http.ClientRequest
. La instancia ClientRequest
es un flujo grabable. Si se necesita cargar un archivo con una solicitud POST, entonces escribir en el objeto ClientRequest
.
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()
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()
Ejemplo usando opciones de tls.connect()
:
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, optar por no utilizar la agrupación de conexiones al no usar un Agent
.
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 => {
// ...
})
Ejemplo usando una URL
como options
:
const options = new URL('https://abc:')
const req = https.request(options, res => {
// ...
})
Ejemplo de fijación en la huella digital del certificado, o la clave pública (similar a pin-sha256
):
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) {
// Asegurarse de que el certificado se emita al host al que estamos conectados
const err = checkServerIdentity(host, cert)
if (err) {
return err
}
// Fijar la clave pública, similar a la fijación HPKP pin-sha256
const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
if (sha256(cert.pubkey) !== pubkey256) {
const msg =
'Error de verificación del certificado: ' +
`La clave pública de '${cert.subject.CN}' ` +
'no coincide con nuestra huella digital fijada'
return new Error(msg)
}
// Fijar el certificado exacto, en lugar de la clave 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 =
'Error de verificación del certificado: ' +
`El certificado de '${cert.subject.CN}' ` +
'no coincide con nuestra huella digital fijada'
return new Error(msg)
}
// Este bucle es solo informativo.
// Imprimir el certificado y las huellas digitales de la clave pública de todos los certificados en la
// cadena. Es común fijar la clave pública del emisor en la pública
// Internet, mientras se fija la clave pública del servicio en sensible
// entornos.
let lastprint256
do {
console.log('Nombre común del sujeto:', cert.subject.CN)
console.log(' Huella digital SHA256 del certificado:', cert.fingerprint256)
const hash = createHash('sha256')
console.log(' Ping-sha256 de clave pública:', 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('Todo OK. El servidor coincidió con nuestro certificado fijado o clave pública')
console.log('statusCode:', res.statusCode)
res.on('data', d => {})
})
req.on('error', e => {
console.error(e.message)
})
req.end()
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) {
// Asegurarse de que el certificado se emita al host al que estamos conectados
const err = tls.checkServerIdentity(host, cert)
if (err) {
return err
}
// Fijar la clave pública, similar a la fijación HPKP pin-sha256
const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
if (sha256(cert.pubkey) !== pubkey256) {
const msg =
'Error de verificación del certificado: ' +
`La clave pública de '${cert.subject.CN}' ` +
'no coincide con nuestra huella digital fijada'
return new Error(msg)
}
// Fijar el certificado exacto, en lugar de la clave 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 =
'Error de verificación del certificado: ' +
`El certificado de '${cert.subject.CN}' ` +
'no coincide con nuestra huella digital fijada'
return new Error(msg)
}
// Este bucle es solo informativo.
// Imprimir el certificado y las huellas digitales de la clave pública de todos los certificados en la
// cadena. Es común fijar la clave pública del emisor en la pública
// Internet, mientras se fija la clave pública del servicio en sensible
// entornos.
do {
console.log('Nombre común del sujeto:', cert.subject.CN)
console.log(' Huella digital SHA256 del certificado:', cert.fingerprint256)
hash = crypto.createHash('sha256')
console.log(' Ping-sha256 de clave pública:', 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('Todo OK. El servidor coincidió con nuestro certificado fijado o clave pública')
console.log('statusCode:', res.statusCode)
res.on('data', d => {})
})
req.on('error', e => {
console.error(e.message)
})
req.end()
Salidas por ejemplo:
Nombre común del sujeto: github.com
Huella digital SHA256 del 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
Ping-sha256 de clave pública: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
Nombre común del sujeto: Sectigo ECC Domain Validation Secure Server CA
Huella digital SHA256 del 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
Ping-sha256 de clave pública: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
Nombre común del sujeto: USERTrust ECC Certification Authority
Huella digital SHA256 del 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
Ping-sha256 de clave pública: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
Nombre común del sujeto: AAA Certificate Services
Huella digital SHA256 del 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
Ping-sha256 de clave pública: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
Todo OK. El servidor coincidió con nuestro certificado fijado o clave pública
statusCode: 200