Skip to content

HTTPS

[Stable: 2 - 安定版]

Stable: 2 安定版: 2 - 安定版

ソースコード: lib/https.js

HTTPSは、TLS/SSL上のHTTPプロトコルです。Node.jsでは、これは別のモジュールとして実装されています。

cryptoサポートが利用できないかの判断

Node.jsは、node:cryptoモジュールのサポートを含めずにビルドされる可能性があります。そのような場合、httpsからのimportを試みるか、require('node:https')を呼び出すと、エラーがスローされます。

CommonJSを使用する場合、スローされたエラーはtry/catchを使用してキャッチできます。

js
let https;
try {
  https = require('node:https');
} catch (err) {
  console.error('httpsサポートは無効になっています!');
}

字句ESMのimportキーワードを使用する場合、エラーは、モジュールをロードする試みの前に process.on('uncaughtException')のハンドラーが登録されている場合にのみキャッチできます(たとえば、プリロードモジュールを使用)。

ESMを使用する場合、コードがcryptoサポートが有効になっていないNode.jsのビルドで実行される可能性がある場合は、字句importキーワードの代わりにimport()関数を使用することを検討してください。

js
let https;
try {
  https = await import('node:https');
} catch (err) {
  console.error('httpsサポートは無効になっています!');
}

Class: https.Agent

[履歴]

バージョン変更点
v5.3.0TLSセッションキャッシュを無効にするために 0 maxCachedSessions をサポート
v2.5.0TLSセッションの再利用のために options にパラメータ maxCachedSessions が追加
v0.4.5v0.4.5 で追加

http.Agentと同様のHTTPS用のAgentオブジェクト。詳細はhttps.request()を参照してください。

new Agent([options])

[履歴]

バージョン変更点
v12.5.0ターゲットホストがIPアドレスを使用して指定されている場合は、servernameを自動的に設定しない
  • options <Object> エージェントに設定する設定可能なオプションのセット。http.Agent(options)と同じフィールドを持つことができ、
    • maxCachedSessions <number> TLSキャッシュセッションの最大数。TLSセッションキャッシュを無効にするには 0 を使用します。デフォルト: 100
    • servername <string> サーバーに送信されるServer Name Indication extensionの値。拡張の送信を無効にするには、空の文字列 '' を使用します。デフォルト: ターゲットサーバーのホスト名。ただし、ターゲットサーバーがIPアドレスを使用して指定されている場合は、デフォルトは '' (拡張なし)です。TLSセッションの再利用に関する情報は、Session Resumptionを参照してください。

イベント: 'keylog'

追加: v13.2.0, v12.16.0

  • line <Buffer> NSS の SSLKEYLOGFILE 形式の ASCII テキスト行。
  • tlsSocket <tls.TLSSocket> それが生成された tls.TLSSocket インスタンス。

keylog イベントは、このエージェントによって管理されている接続でキーマテリアルが生成または受信されたときに発生します(通常はハンドシェイクが完了する前ですが、必ずしもそうとは限りません)。このキーマテリアルは、キャプチャされたTLSトラフィックを復号化できるため、デバッグ用に保存できます。ソケットごとに複数回発生する可能性があります。

典型的なユースケースは、受信した行を共通のテキストファイルに追加し、後でソフトウェア(Wiresharkなど)がトラフィックを復号化するために使用することです。

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

クラス: https.Server

追加: v0.3.4

詳細については、http.Server を参照してください。

server.close([callback])

追加: v0.1.90

node:http モジュールの server.close() を参照してください。

server[Symbol.asyncDispose]()

追加: v20.4.0

[Stable: 1 - Experimental]

Stable: 1 Stability: 1 - 試験的

server.close() を呼び出し、サーバーが閉じられたときに解決される Promise を返します。

server.closeAllConnections()

追加: v18.2.0

node:http モジュールの server.closeAllConnections() を参照してください。

server.closeIdleConnections()

追加: v18.2.0

node:http モジュールの server.closeIdleConnections() を参照してください。

server.headersTimeout

Added in: v11.3.0

node:http モジュールの server.headersTimeout を参照してください。

server.listen()

暗号化された接続をリッスンする HTTPS サーバーを起動します。このメソッドは、net.Serverserver.listen() と同じです。

server.maxHeadersCount

node:http モジュールの server.maxHeadersCount を参照してください。

server.requestTimeout

[履歴]

バージョン変更
v18.0.0デフォルトのリクエストタイムアウトが、タイムアウトなしから 300 秒 (5 分) に変更されました。
v14.11.0Added in: v14.11.0

node:http モジュールの server.requestTimeout を参照してください。

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

Added in: v0.11.2

node:http モジュールの server.setTimeout() を参照してください。

server.timeout

[履歴]

バージョン変更
v13.0.0デフォルトのタイムアウトが 120 秒から 0 (タイムアウトなし) に変更されました。
v0.11.2Added in: v0.11.2
  • <number> Default: 0 (タイムアウトなし)

node:http モジュールの server.timeout を参照してください。

server.keepAliveTimeout

追加: v8.0.0

node:http モジュールの server.keepAliveTimeout を参照してください。

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

追加: 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);

または

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

この例の証明書とキーを生成するには、次を実行します。

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

次に、この例の pfx 証明書を生成するには、次を実行します。

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

[履歴]

バージョン変更
v10.9.0url パラメーターを個別の options オブジェクトとともに渡せるようになりました。
v7.5.0options パラメーターは WHATWG URL オブジェクトにできます。
v0.3.6追加: v0.3.6

http.get() と同様ですが、HTTPS 用です。

options は、オブジェクト、文字列、または URL オブジェクトにできます。 options が文字列の場合、new URL() で自動的に解析されます。 URL オブジェクトの場合、通常の 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

[履歴]

バージョン変更
v19.0.0エージェントはデフォルトで HTTP Keep-Alive と 5 秒のタイムアウトを使用するようになりました。
v0.5.9追加: v0.5.9

すべての HTTPS クライアントリクエストに対する https.Agent のグローバルインスタンス。keepAlive が有効で、timeout が 5 秒である点で、デフォルトの https.Agent 設定とは異なります。

https.request(options[, callback])

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

[履歴]

バージョン変更
v22.4.0, v20.16.0clientCertEngine オプションは、OpenSSL のカスタムエンジンサポートに依存していますが、OpenSSL 3 では非推奨です。
v16.7.0, v14.18.0URL オブジェクトを使用する場合、解析されたユーザー名とパスワードは適切に URI デコードされるようになりました。
v14.1.0, v13.14.0highWaterMark オプションが受け入れられるようになりました。
v10.9.0url パラメータを個別の options オブジェクトとともに渡すことができるようになりました。
v9.3.0options パラメータに clientCertEngine を含めることができるようになりました。
v7.5.0options パラメータは WHATWG URL オブジェクトにすることができます。
v0.3.6追加: v0.3.6

セキュアなウェブサーバーにリクエストを送信します。

tls.connect() の以下の追加の options も受け入れられます: ca, cert, ciphers, clientCertEngine (非推奨), crl, dhparam, ecdhCurve, honorCipherOrder, key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext, highWaterMark.

options は、オブジェクト、文字列、または URL オブジェクトにすることができます。options が文字列の場合、new URL() で自動的に解析されます。URL オブジェクトの場合、自動的に通常の options オブジェクトに変換されます。

https.request() は、http.ClientRequest クラスのインスタンスを返します。ClientRequest インスタンスは書き込み可能なストリームです。POST リクエストでファイルをアップロードする必要がある場合は、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();

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) => {
  // ...
});

あるいは、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) => {
  // ...
});

URLoptions として使用する例:

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

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

証明書のフィンガープリント、または公開鍵(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();

出力例:

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