Skip to content

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:

js
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:

js
let https;
try {
  https = await import('node:https');
} catch (err) {
  console.error('il supporto https è disabilitato!');
}

Classe: https.Agent

[Cronologia]

VersioneModifiche
v5.3.0supporta 0 maxCachedSessions per disabilitare la memorizzazione nella cache della sessione TLS.
v2.5.0parametro maxCachedSessions aggiunto a options per il riutilizzo delle sessioni TLS.
v0.4.5Aggiunto in: v0.4.5

Un oggetto Agent per HTTPS simile a http.Agent. Vedere https.request() per maggiori informazioni.

new Agent([options])

[Cronologia]

VersioneModifiche
v12.5.0non 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 di http.Agent(options), e
    • maxCachedSessions <number> numero massimo di sessioni TLS memorizzate nella cache. Utilizzare 0 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). Vedere Ripresa 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 NSS SSLKEYLOGFILE.
  • tlsSocket <tls.TLSSocket> L'istanza tls.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:

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

Classe: https.Server

Aggiunto in: v0.3.4

Vedere http.Server per ulteriori informazioni.

server.close([callback])

Aggiunto in: v0.1.90

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

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

Vedere server.maxHeadersCount nel modulo node:http.

server.requestTimeout

[Cronologia]

VersioneModifiche
v18.0.0Il timeout predefinito della richiesta è cambiato da nessun timeout a 300s (5 minuti).
v14.11.0Aggiunto in: v14.11.0

Vedere server.requestTimeout nel modulo node:http.

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

Aggiunto in: v0.11.2

Vedere server.setTimeout() nel modulo node:http.

server.timeout

[Cronologia]

VersioneModifiche
v13.0.0Il timeout predefinito è cambiato da 120s a 0 (nessun timeout).
v0.11.2Aggiunto in: v0.11.2
  • <number> Predefinito: 0 (nessun timeout)

Vedere server.timeout nel modulo node:http.

server.keepAliveTimeout

Aggiunto in: v8.0.0

Vedi server.keepAliveTimeout nel modulo node:http.

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

Aggiunto in: 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);

Oppure

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);

Per generare il certificato e la chiave per questo esempio, esegui:

bash
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:

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])

[Cronologia]

VersioneModifiche
v10.9.0Il parametro url può ora essere passato insieme a un oggetto options separato.
v7.5.0Il parametro options può essere un oggetto WHATWG URL.
v0.3.6Aggiunto in: v0.3.6

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.

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

[Cronologia]

VersioneModifiche
v19.0.0L'agente ora utilizza HTTP Keep-Alive e un timeout di 5 secondi per impostazione predefinita.
v0.5.9Aggiunto 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]

VersioneModifiche
v22.4.0, v20.16.0L'opzione clientCertEngine dipende dal supporto del motore personalizzato in OpenSSL che è deprecato in OpenSSL 3.
v16.7.0, v14.18.0Quando si utilizza un oggetto URL analizzato, username e password verranno ora decodificati correttamente tramite URI.
v14.1.0, v13.14.0L'opzione highWaterMark è ora accettata.
v10.9.0Il parametro url può ora essere passato insieme a un oggetto options separato.
v9.3.0Il parametro options può ora includere clientCertEngine.
v7.5.0Il parametro options può essere un oggetto WHATWG URL.
v0.3.6Aggiunto in: v0.3.6

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.

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();

Esempio che utilizza le opzioni da 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) => {
  // ...
});

In alternativa, rinuncia al pool di connessioni non utilizzando un 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) => {
  // ...
});

Esempio che utilizza una URL come options:

js
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):

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) {
    // 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();
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) {
    // 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:

text
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