HTTPS
[Stabile: 2 - Stabile]
Stabile: 2 Stabilità: 2 - Stabile
Codice sorgente: lib/https.js
HTTPS è il protocollo HTTP su TLS/SSL. In Node.js questo è implementato come un modulo separato.
Determinare se il supporto crypto non è disponibile
È possibile che Node.js sia compilato senza includere il supporto per il modulo node:crypto
. In tali casi, tentare di import
da https
o chiamare require('node:https')
comporterà la generazione di un errore.
Quando si utilizza CommonJS, l'errore generato può essere intercettato utilizzando try/catch:
let https;
try {
https = require('node:https');
} catch (err) {
console.error('il supporto https è disabilitato!');
}
Quando si utilizza la parola chiave lessicale ESM import
, l'errore può essere intercettato solo se un gestore per process.on('uncaughtException')
viene registrato prima che venga effettuato qualsiasi tentativo di caricare il modulo (utilizzando, ad esempio, un modulo di precaricamento).
Quando si utilizza ESM, se esiste la possibilità che il codice possa essere eseguito su una build di Node.js in cui il supporto crypto non è abilitato, considera l'utilizzo della funzione import()
invece della parola chiave lessicale import
:
let https;
try {
https = await import('node:https');
} catch (err) {
console.error('il supporto https è disabilitato!');
}
Classe: https.Agent
[Cronologia]
Versione | Modifiche |
---|---|
v5.3.0 | supporta 0 maxCachedSessions per disabilitare la memorizzazione nella cache della sessione TLS. |
v2.5.0 | parametro maxCachedSessions aggiunto a options per il riutilizzo delle sessioni TLS. |
v0.4.5 | Aggiunto in: v0.4.5 |
Un oggetto Agent
per HTTPS simile a http.Agent
. Vedere https.request()
per maggiori informazioni.
new Agent([options])
[Cronologia]
Versione | Modifiche |
---|---|
v12.5.0 | non impostare automaticamente il nome del server se l'host di destinazione è stato specificato utilizzando un indirizzo IP. |
options
<Object> Insieme di opzioni configurabili da impostare sull'agente. Può avere gli stessi campi dihttp.Agent(options)
, emaxCachedSessions
<number> numero massimo di sessioni TLS memorizzate nella cache. Utilizzare0
per disabilitare la memorizzazione nella cache delle sessioni TLS. Predefinito:100
.servername
<string> il valore dell'estensione Server Name Indication da inviare al server. Utilizzare una stringa vuota''
per disabilitare l'invio dell'estensione. Predefinito: nome host del server di destinazione, a meno che il server di destinazione non sia specificato utilizzando un indirizzo IP, nel qual caso il valore predefinito è''
(nessuna estensione). VedereRipresa della sessione
per informazioni sul riutilizzo della sessione TLS.
Evento: 'keylog'
Aggiunto in: v13.2.0, v12.16.0
line
<Buffer> Riga di testo ASCII, in formato NSSSSLKEYLOGFILE
.tlsSocket
<tls.TLSSocket> L'istanzatls.TLSSocket
su cui è stata generata.
L'evento keylog
viene emesso quando il materiale chiave viene generato o ricevuto da una connessione gestita da questo agente (in genere prima che l'handshake sia completo, ma non necessariamente). Questo materiale chiave può essere memorizzato per il debug, poiché consente di decrittografare il traffico TLS catturato. Può essere emesso più volte per ciascun socket.
Un caso d'uso tipico è quello di aggiungere le righe ricevute a un file di testo comune, che viene successivamente utilizzato da un software (come Wireshark) per decrittografare il traffico:
// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 });
});
Classe: https.Server
Aggiunto in: v0.3.4
- Estende: <tls.Server>
Vedere http.Server
per ulteriori informazioni.
server.close([callback])
Aggiunto in: v0.1.90
callback
<Function>- Restituisce: <https.Server>
Vedere server.close()
nel modulo node:http
.
server[Symbol.asyncDispose]()
Aggiunto in: v20.4.0
[Stabile: 1 - Sperimentale]
Stabile: 1 Stabilità: 1 - Sperimentale
Chiama server.close()
e restituisce una promise che si adempie quando il server è stato chiuso.
server.closeAllConnections()
Aggiunto in: v18.2.0
Vedere server.closeAllConnections()
nel modulo node:http
.
server.closeIdleConnections()
Aggiunto in: v18.2.0
Vedere server.closeIdleConnections()
nel modulo node:http
.
server.headersTimeout
Aggiunto in: v11.3.0
- <number> Predefinito:
60000
Vedere server.headersTimeout
nel modulo node:http
.
server.listen()
Avvia il server HTTPS in ascolto di connessioni crittografate. Questo metodo è identico a server.listen()
da net.Server
.
server.maxHeadersCount
- <number> Predefinito:
2000
Vedere server.maxHeadersCount
nel modulo node:http
.
server.requestTimeout
[Cronologia]
Versione | Modifiche |
---|---|
v18.0.0 | Il timeout predefinito della richiesta è cambiato da nessun timeout a 300s (5 minuti). |
v14.11.0 | Aggiunto in: v14.11.0 |
- <number> Predefinito:
300000
Vedere server.requestTimeout
nel modulo node:http
.
server.setTimeout([msecs][, callback])
Aggiunto in: v0.11.2
msecs
<number> Predefinito:120000
(2 minuti)callback
<Function>- Restituisce: <https.Server>
Vedere server.setTimeout()
nel modulo node:http
.
server.timeout
[Cronologia]
Versione | Modifiche |
---|---|
v13.0.0 | Il timeout predefinito è cambiato da 120s a 0 (nessun timeout). |
v0.11.2 | Aggiunto in: v0.11.2 |
- <number> Predefinito: 0 (nessun timeout)
Vedere server.timeout
nel modulo node:http
.
server.keepAliveTimeout
Aggiunto in: v8.0.0
- <number> Predefinito:
5000
(5 secondi)
Vedi server.keepAliveTimeout
nel modulo node:http
.
https.createServer([options][, requestListener])
Aggiunto in: v0.3.4
options
<Object> Accettaoptions
datls.createServer()
,tls.createSecureContext()
ehttp.createServer()
.requestListener
<Function> Un listener da aggiungere all'evento'request'
.- Restituisce: <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);
Oppure
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);
Per generare il certificato e la chiave per questo esempio, esegui:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
-keyout private-key.pem -out certificate.pem
Quindi, per generare il certificato pfx
per questo esempio, esegui:
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])
[Cronologia]
Versione | Modifiche |
---|---|
v10.9.0 | Il parametro url può ora essere passato insieme a un oggetto options separato. |
v7.5.0 | Il parametro options può essere un oggetto WHATWG URL . |
v0.3.6 | Aggiunto in: v0.3.6 |
url
<stringa> | <URL>options
<Oggetto> | <stringa> | <URL> Accetta le stesseoptions
dihttps.request()
, con il metodo impostato su GET per impostazione predefinita.callback
<Funzione>
Come http.get()
ma per HTTPS.
options
può essere un oggetto, una stringa o un oggetto URL
. Se options
è una stringa, viene automaticamente analizzata con new URL()
. Se è un oggetto URL
, verrà automaticamente convertito in un normale oggetto options
.
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
[Cronologia]
Versione | Modifiche |
---|---|
v19.0.0 | L'agente ora utilizza HTTP Keep-Alive e un timeout di 5 secondi per impostazione predefinita. |
v0.5.9 | Aggiunto in: v0.5.9 |
Istanza globale di https.Agent
per tutte le richieste client HTTPS. Differisce da una configurazione predefinita di https.Agent
avendo keepAlive
abilitato e un timeout
di 5 secondi.
https.request(options[, callback])
https.request(url[, options][, callback])
[Cronologia]
Versione | Modifiche |
---|---|
v22.4.0, v20.16.0 | L'opzione clientCertEngine dipende dal supporto del motore personalizzato in OpenSSL che è deprecato in OpenSSL 3. |
v16.7.0, v14.18.0 | Quando si utilizza un oggetto URL analizzato, username e password verranno ora decodificati correttamente tramite URI. |
v14.1.0, v13.14.0 | L'opzione highWaterMark è ora accettata. |
v10.9.0 | Il parametro url può ora essere passato insieme a un oggetto options separato. |
v9.3.0 | Il parametro options può ora includere clientCertEngine . |
v7.5.0 | Il parametro options può essere un oggetto WHATWG URL . |
v0.3.6 | Aggiunto in: v0.3.6 |
options
<Oggetto> | <stringa> | <URL> Accetta tutte leoptions
dahttp.request()
, con alcune differenze nei valori predefiniti:protocol
Predefinito:'https:'
port
Predefinito:443
agent
Predefinito:https.globalAgent
callback
<Funzione>Restituisce: <http.ClientRequest>
Effettua una richiesta a un server web sicuro.
Sono accettate anche le seguenti options
aggiuntive da tls.connect()
: ca
, cert
, ciphers
, clientCertEngine
(deprecato), crl
, dhparam
, ecdhCurve
, honorCipherOrder
, key
, passphrase
, pfx
, rejectUnauthorized
, secureOptions
, secureProtocol
, servername
, sessionIdContext
, highWaterMark
.
options
può essere un oggetto, una stringa o un oggetto URL
. Se options
è una stringa, viene automaticamente analizzata con new URL()
. Se è un oggetto URL
, verrà automaticamente convertito in un oggetto options
ordinario.
https.request()
restituisce un'istanza della classe http.ClientRequest
. L'istanza ClientRequest
è uno stream scrivibile. Se è necessario caricare un file con una richiesta POST, allora scrivi sull'oggetto 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();
Esempio che utilizza le opzioni da 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) => {
// ...
});
In alternativa, rinuncia al pool di connessioni non utilizzando 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) => {
// ...
});
Esempio che utilizza una URL
come options
:
const options = new URL('https://abc:');
const req = https.request(options, (res) => {
// ...
});
Esempio di pinning sull'impronta digitale del certificato o sulla chiave pubblica (simile 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();
Output ad esempio:
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