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 utiliza CommonJS, el error que se produce se puede capturar utilizando try/catch:
let https;
try {
https = require('node:https');
} catch (err) {
console.error('¡el soporte de https está desactivado!');
}
Cuando se utiliza 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 intente cargar el módulo (utilizando, por ejemplo, un módulo de precarga).
Cuando se utiliza 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á desactivado!');
}
Clase: https.Agent
[Historial]
Versión | Cambios |
---|---|
v5.3.0 | admite 0 maxCachedSessions para deshabilitar el almacenamiento en caché de sesiones TLS. |
v2.5.0 | parámetro maxCachedSessions añadido a options para la reutilización de sesiones TLS. |
v0.4.5 | Añadido 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 establezca automáticamente servername si el host de destino se especificó utilizando 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 Extensión de indicación de nombre de servidor que se enviará al servidor. Utilice 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 utilizando 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 la sesión TLS.
Evento: 'keylog'
Agregado en: v13.2.0, v12.16.0
line
<Buffer> Línea de texto ASCII, en formatoSSLKEYLOGFILE
de NSS.tlsSocket
<tls.TLSSocket> La instanciatls.TLSSocket
en la que se generó.
El evento keylog
se emite cuando el material de la 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 puede ser almacenado para la depuración, ya que permite que el tráfico TLS capturado sea descifrado. Puede ser emitido 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 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()
Inicia el servidor HTTPS escuchando 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 300s (5 minutos). |
v14.11.0 | Agregado en: v14.11.0 |
- <number> Predeterminado:
300000
Ver server.requestTimeout
en el módulo node:http
.
server.setTimeout([msecs][, callback])
Agregado 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
Añadido en: v8.0.0
- <number> Predeterminado:
5000
(5 segundos)
Ver server.keepAliveTimeout
en el módulo node:http
.
https.createServer([options][, requestListener])
Añadido en: v0.3.4
options
<Object> Aceptaoptions
detls.createServer()
,tls.createSecureContext()
yhttp.createServer()
.requestListener
<Function> Un listener que se añadirá al evento'request'
.- Devuelve: <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 URL WHATWG. |
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 por defecto.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 usa HTTP Keep-Alive y un tiempo de espera de 5 segundos de forma predeterminada. |
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á obsoleto en OpenSSL 3. |
v16.7.0, v14.18.0 | Al usar un objeto URL analizado, el nombre de usuario y la contraseña ahora se decodificarán correctamente en URI. |
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 WHATWG URL . |
v0.3.6 | Añadido en: v0.3.6 |
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.
Las siguientes options
adicionales de tls.connect()
también se aceptan: 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 de escritura. Si se necesita cargar un archivo con una solicitud POST, entonces escriba 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, opte 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 en 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) {
// Make sure the certificate is issued to the host we are connected to
const err = checkServerIdentity(host, cert);
if (err) {
return err;
}
// Pin the public key, similar to HPKP pin-sha256 pinning
const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=';
if (sha256(cert.pubkey) !== pubkey256) {
const msg = 'Certificate verification error: ' +
`The public key of '${cert.subject.CN}' ` +
'does not match our pinned fingerprint';
return new Error(msg);
}
// Pin the exact certificate, rather than the pub key
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 = 'Certificate verification error: ' +
`The certificate of '${cert.subject.CN}' ` +
'does not match our pinned fingerprint';
return new Error(msg);
}
// This loop is informational only.
// Print the certificate and public key fingerprints of all certs in the
// chain. Its common to pin the public key of the issuer on the public
// internet, while pinning the public key of the service in sensitive
// environments.
let lastprint256;
do {
console.log('Subject Common Name:', cert.subject.CN);
console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256);
const hash = createHash('sha256');
console.log(' Public key 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('All OK. Server matched our pinned cert or public key');
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) {
// Make sure the certificate is issued to the host we are connected to
const err = tls.checkServerIdentity(host, cert);
if (err) {
return err;
}
// Pin the public key, similar to HPKP pin-sha256 pinning
const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=';
if (sha256(cert.pubkey) !== pubkey256) {
const msg = 'Certificate verification error: ' +
`The public key of '${cert.subject.CN}' ` +
'does not match our pinned fingerprint';
return new Error(msg);
}
// Pin the exact certificate, rather than the pub key
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 = 'Certificate verification error: ' +
`The certificate of '${cert.subject.CN}' ` +
'does not match our pinned fingerprint';
return new Error(msg);
}
// This loop is informational only.
// Print the certificate and public key fingerprints of all certs in the
// chain. Its common to pin the public key of the issuer on the public
// internet, while pinning the public key of the service in sensitive
// environments.
do {
console.log('Subject Common Name:', cert.subject.CN);
console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256);
hash = crypto.createHash('sha256');
console.log(' Public key 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('All OK. Server matched our pinned cert or public key');
console.log('statusCode:', res.statusCode);
res.on('data', (d) => {});
});
req.on('error', (e) => {
console.error(e.message);
});
req.end();
Salidas por ejemplo:
Subject Common Name: github.com
Certificate SHA256 fingerprint: 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
Public key ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
Subject Common Name: Sectigo ECC Domain Validation Secure Server CA
Certificate SHA256 fingerprint: 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
Public key ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
Subject Common Name: USERTrust ECC Certification Authority
Certificate SHA256 fingerprint: 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
Public key ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
Subject Common Name: AAA Certificate Services
Certificate SHA256 fingerprint: 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
Public key ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
All OK. Server matched our pinned cert or public key
statusCode: 200