Skip to content

HTTPS

[Stable : 2 - Stable]

Stable : 2 Stability : 2 - Stable

Source Code : lib/https.js

HTTPS est le protocole HTTP sur TLS/SSL. Dans Node.js, il est implémenté comme un module séparé.

Déterminer si la prise en charge du chiffrement n'est pas disponible

Il est possible que Node.js soit compilé sans inclure la prise en charge du module node:crypto. Dans de tels cas, tenter d'importer depuis https ou d'appeler require('node:https') entraînera le lancement d'une erreur.

Lors de l'utilisation de CommonJS, l'erreur levée peut être interceptée à l'aide de try/catch :

js
let https
try {
  https = require('node:https')
} catch (err) {
  console.error('La prise en charge de https est désactivée !')
}

Lors de l'utilisation du mot clé import ESM lexical, l'erreur ne peut être interceptée que si un gestionnaire pour process.on('uncaughtException') est enregistré avant toute tentative de chargement du module (à l'aide, par exemple, d'un module de préchargement).

Lors de l'utilisation d'ESM, s'il existe une chance que le code puisse être exécuté sur une version de Node.js où la prise en charge du chiffrement n'est pas activée, envisagez d'utiliser la fonction import() au lieu du mot clé import lexical :

js
let https
try {
  https = await import('node:https')
} catch (err) {
  console.error('La prise en charge de https est désactivée !')
}

Class : https.Agent

[Historique]

VersionModifications
v5.3.0prise en charge de 0 maxCachedSessions pour désactiver la mise en cache des sessions TLS.
v2.5.0paramètre maxCachedSessions ajouté à options pour la réutilisation des sessions TLS.
v0.4.5Ajouté dans : v0.4.5

Un objet Agent pour HTTPS similaire à http.Agent. Voir https.request() pour plus d'informations.

new Agent([options])

[Historique]

VersionModifications
v12.5.0ne définit pas automatiquement le nom de serveur si l'hôte cible a été spécifié à l'aide d'une adresse IP.
  • options <Object> Ensemble d'options configurables à définir sur l'agent. Peut avoir les mêmes champs que pour http.Agent(options), et
    • maxCachedSessions <number> nombre maximal de sessions TLS mises en cache. Utilisez 0 pour désactiver la mise en cache des sessions TLS. Valeur par défaut : 100.
    • servername <string> la valeur de l'extension Server Name Indication à envoyer au serveur. Utilisez la chaîne vide '' pour désactiver l'envoi de l'extension. Valeur par défaut : nom d'hôte du serveur cible, sauf si le serveur cible est spécifié à l'aide d'une adresse IP, auquel cas la valeur par défaut est '' (aucune extension). Voir Reprise de session pour plus d'informations sur la réutilisation des sessions TLS.

Événement : 'keylog'

Ajouté dans : v13.2.0, v12.16.0

  • line <Buffer> Ligne de texte ASCII, au format NSS SSLKEYLOGFILE.
  • tlsSocket <tls.TLSSocket> L'instance tls.TLSSocket sur laquelle elle a été générée.

L'événement keylog est émis lorsqu'un matériel de chiffrement est généré ou reçu par une connexion gérée par cet agent (généralement avant que la négociation de chiffrement ne soit terminée, mais pas nécessairement). Ce matériel de chiffrement peut être stocké pour le débogage, car il permet de décrypter le trafic TLS capturé. Il peut être émis plusieurs fois pour chaque socket.

Un cas d'utilisation typique consiste à ajouter les lignes reçues à un fichier texte commun, qui est ensuite utilisé par un logiciel (tel que Wireshark) pour décrypter le trafic :

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

Classe : https.Server

Ajouté dans : v0.3.4

Voir http.Server pour plus d'informations.

server.close([callback])

Ajouté dans : v0.1.90

Voir server.close() dans le module node:http.

server[Symbol.asyncDispose]()

Ajouté dans : v20.4.0

[Stable : 1 - Expérimental]

Stable : 1 Stabilité : 1 - Expérimental

Appelez server.close() et renvoie une promesse qui se résout lorsque le serveur est fermé.

server.closeAllConnections()

Ajouté dans : v18.2.0

Voir server.closeAllConnections() dans le module node:http.

server.closeIdleConnections()

Ajouté dans : v18.2.0

Voir server.closeIdleConnections() dans le module node:http.

server.headersTimeout

Ajouté dans : v11.3.0

Voir server.headersTimeout dans le module node:http.

server.listen()

Démarre le serveur HTTPS à l'écoute des connexions chiffrées. Cette méthode est identique à server.listen() de net.Server.

server.maxHeadersCount

Voir server.maxHeadersCount dans le module node:http.

server.requestTimeout

[Historique]

VersionModifications
v18.0.0Le délai d'attente de requête par défaut est passé de pas de délai d'attente à 300 s (5 minutes).
v14.11.0Ajouté dans : v14.11.0

Voir server.requestTimeout dans le module node:http.

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

Ajouté dans : v0.11.2

Voir server.setTimeout() dans le module node:http.

server.timeout

[Historique]

VersionModifications
v13.0.0Le délai d'attente par défaut est passé de 120 s à 0 (pas de délai d'attente).
v0.11.2Ajouté dans : v0.11.2
  • <nombre> Défaut : 0 (pas de délai d'attente)

Voir server.timeout dans le module node:http.

server.keepAliveTimeout

Ajouté dans : v8.0.0

Voir server.keepAliveTimeout dans le module node:http.

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

Ajouté dans : 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)

Pour générer le certificat et la clé pour cet exemple, exécutez :

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

Ensuite, pour générer le certificat pfx pour cet exemple, exécutez :

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

[Historique]

VersionModifications
v10.9.0Le paramètre url peut maintenant être passé avec un objet options séparé.
v7.5.0Le paramètre options peut être un objet URL WHATWG.
v0.3.6Ajouté dans : v0.3.6

Comme http.get() mais pour HTTPS.

options peut être un objet, une chaîne de caractères ou un objet URL. Si options est une chaîne de caractères, elle est automatiquement analysée avec new URL(). Si c'est un objet URL, il sera automatiquement converti en un objet options ordinaire.

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

[Historique]

VersionModifications
v19.0.0L'agent utilise maintenant HTTP Keep-Alive et un délai d'attente de 5 secondes par défaut.
v0.5.9Ajouté dans : v0.5.9

Instance globale de https.Agent pour toutes les requêtes client HTTPS. Diffère d'une configuration https.Agent par défaut en ayant keepAlive activé et un timeout de 5 secondes.

https.request(options[, callback])

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

[Historique]

VersionModifications
v22.4.0, v20.16.0L'option clientCertEngine dépend de la prise en charge du moteur personnalisé dans OpenSSL, qui est obsolète dans OpenSSL 3.
v16.7.0, v14.18.0Lors de l'utilisation d'un objet URL, le nom d'utilisateur et le mot de passe analysés seront désormais correctement décodés en URI.
v14.1.0, v13.14.0L'option highWaterMark est désormais acceptée.
v10.9.0Le paramètre url peut désormais être passé avec un objet options séparé.
v9.3.0Le paramètre options peut désormais inclure clientCertEngine.
v7.5.0Le paramètre options peut être un objet URL WHATWG.
v0.3.6Ajouté dans : v0.3.6

Effectue une requête à un serveur web sécurisé.

Les options supplémentaires suivantes de tls.connect() sont également acceptées : ca, cert, ciphers, clientCertEngine (déprécié), crl, dhparam, ecdhCurve, honorCipherOrder, key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext, highWaterMark.

options peut être un objet, une chaîne ou un objet URL. Si options est une chaîne, elle est automatiquement analysée avec new URL(). Si c'est un objet URL, il sera automatiquement converti en un objet options ordinaire.

https.request() retourne une instance de la classe http.ClientRequest. L'instance ClientRequest est un flux inscriptible. Si l'on a besoin de télécharger un fichier avec une requête POST, alors écrire sur l'objet 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()

Exemple utilisant les options 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 => {
  // ...
})

Alternativement, désactivez la mise en commun des connexions en n'utilisant pas d'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 => {
  // ...
})

Exemple utilisant un URL comme options :

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

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

Exemple d'épingle sur l'empreinte digitale du certificat ou la clé publique (similaire à 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) {
    // Assurez-vous que le certificat est émis pour l'hôte auquel nous sommes connectés
    const err = checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // Épinglez la clé publique, similaire à l'épingle HPKP pin-sha256
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'Erreur de vérification du certificat : ' +
        `La clé publique de '${cert.subject.CN}' ` +
        'ne correspond pas à notre empreinte digitale épinglée'
      return new Error(msg)
    }

    // Épinglez le certificat exact, plutôt que la clé publique
    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 =
        'Erreur de vérification du certificat : ' +
        `Le certificat de '${cert.subject.CN}' ` +
        'ne correspond pas à notre empreinte digitale épinglée'
      return new Error(msg)
    }

    // Cette boucle est uniquement informative.
    // Affichez les empreintes digitales du certificat et de la clé publique de tous les certificats de la
    // chaîne. Il est courant d'épingler la clé publique de l'émetteur sur le public
    // Internet, tout en épinglant la clé publique du service dans des environnements sensibles.
    let lastprint256
    do {
      console.log('Nom commun du sujet :', cert.subject.CN)
      console.log('  Empreinte digitale SHA256 du certificat :', cert.fingerprint256)

      const hash = createHash('sha256')
      console.log('  Épingle ping-sha256 de la clé publique :', 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('Tout est OK. Le serveur correspond à notre certificat ou clé publique épinglée')
  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) {
    // Assurez-vous que le certificat est émis pour l'hôte auquel nous sommes connectés
    const err = tls.checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // Épinglez la clé publique, similaire à l'épingle HPKP pin-sha256
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'Erreur de vérification du certificat : ' +
        `La clé publique de '${cert.subject.CN}' ` +
        'ne correspond pas à notre empreinte digitale épinglée'
      return new Error(msg)
    }

    // Épinglez le certificat exact, plutôt que la clé publique
    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 =
        'Erreur de vérification du certificat : ' +
        `Le certificat de '${cert.subject.CN}' ` +
        'ne correspond pas à notre empreinte digitale épinglée'
      return new Error(msg)
    }

    // Cette boucle est uniquement informative.
    // Affichez les empreintes digitales du certificat et de la clé publique de tous les certificats de la
    // chaîne. Il est courant d'épingler la clé publique de l'émetteur sur le public
    // Internet, tout en épinglant la clé publique du service dans des environnements sensibles.
    do {
      console.log('Nom commun du sujet :', cert.subject.CN)
      console.log('  Empreinte digitale SHA256 du certificat :', cert.fingerprint256)

      hash = crypto.createHash('sha256')
      console.log('  Épingle ping-sha256 de la clé publique :', 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('Tout est OK. Le serveur correspond à notre certificat ou clé publique épinglée')
  console.log('statusCode:', res.statusCode)

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

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

Sorties par exemple :

text
Nom commun du sujet : github.com
  Empreinte digitale SHA256 du certificat : 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
  Épingle ping-sha256 de la clé publique : SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
Nom commun du sujet : Sectigo ECC Domain Validation Secure Server CA
  Empreinte digitale SHA256 du certificat : 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
  Épingle ping-sha256 de la clé publique : Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
Nom commun du sujet : USERTrust ECC Certification Authority
  Empreinte digitale SHA256 du certificat : 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
  Épingle ping-sha256 de la clé publique : UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
Nom commun du sujet : AAA Certificate Services
  Empreinte digitale SHA256 du certificat : 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
  Épingle ping-sha256 de la clé publique : vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
Tout est OK. Le serveur correspond à notre certificat ou clé publique épinglée
statusCode: 200