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サポートは無効です!')
}

クラス: https.Agent

[履歴]

バージョン変更点
v5.3.0TLS セッションキャッシュを無効にするために0 maxCachedSessionsをサポート。
v2.5.0TLS セッション再利用のためのoptionsにパラメータmaxCachedSessionsが追加。
v0.4.5追加: v0.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 拡張の値。拡張機能を送信しないようにするには、空の文字列''を使用します。デフォルト: ターゲットサーバーが IP アドレスを使用して指定されている場合を除き、ターゲットサーバーのホスト名。その場合はデフォルトは '' (拡張機能なし)です。TLS セッションの再利用については、セッションの再開を参照してください。

イベント: '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

[安定版: 1 - 試験的]

安定版: 1 安定版: 1 - 試験的

server.close() を呼び出し、サーバーが閉じられたときに完了するプロミスを返します。

server.closeAllConnections()

追加: v18.2.0

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

server.closeIdleConnections()

追加: v18.2.0

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

server.headersTimeout

追加: 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.0追加: v14.11.0

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

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

追加: v0.11.2

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

server.timeout

[履歴]

バージョン変更点
v13.0.0デフォルトのタイムアウトが 120 秒から 0(タイムアウトなし)に変更されました。
v0.11.2追加: v0.11.2
  • <number> デフォルト: 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.6v0.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.9v0.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 3 で非推奨になった OpenSSL のカスタムエンジンサポートに依存しています。
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.6v0.3.6 で追加されました。

セキュアな Web サーバーへのリクエストを行います。

tls.connect() からの以下の追加の options も受け入れられます: cacertciphersclientCertEngine (非推奨)、crldhparamecdhCurvehonorCipherOrderkeypassphrasepfxrejectUnauthorizedsecureOptionssecureProtocolservernamesessionIdContexthighWaterMark

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