HTTPS
Стабильность: 2 — Стабильный
HTTPS — это протокол HTTP поверх TLS/SSL. В Node.js он реализован в виде отдельного модуля.
Определение недоступности поддержки криптографии
Node.js может быть собран без поддержки модуля node:crypto. В таких случаях попытка выполнить import из https или вызов require('node:https') приведут к возникновению ошибки.
При использовании CommonJS возникшую ошибку можно перехватить с помощью try/catch:
let https;
try {
https = require('node:https');
} catch (err) {
console.error('https support is disabled!');
}
cjscopy
При использовании лексического ключевого слова ESM import ошибку можно перехватить, только если обработчик для process.on('uncaughtException') зарегистрирован до любой попытки загрузить модуль (например, с помощью модуля предварительной загрузки).
При использовании ESM, если есть вероятность, что код будет выполняться в сборке Node.js без поддержки криптографии, рассмотрите возможность использования функции import() вместо лексического ключевого слова import:
let https;
try {
https = await import('node:https');
} catch (err) {
console.error('https support is disabled!');
}
mjscopyКласс: https.Agent
Объект Agent для HTTPS, аналогичный http.Agent. Дополнительные сведения см. в разделе https.request().
Как и у http.Agent, метод createConnection(options[, callback]) можно переопределить, чтобы настроить установление TLS-соединений.
Сведения о переопределении этого метода, включая асинхронное создание сокета с помощью callback-функции, см. в разделе
agent.createConnection().
new Agent([options])
-
options<Object>Набор настраиваемых параметров агента. Может содержать те же поля, что иhttp.Agent(options), а также-
maxCachedSessions<number>максимальное количество кэшируемых сеансов TLS. Используйте0, чтобы отключить кэширование сеансов TLS. По умолчанию:100. -
servername<string>значение расширения Server Name Indication, отправляемое серверу. Используйте пустую строку'', чтобы отключить отправку расширения. По умолчанию: имя узла целевого сервера, если только целевой сервер не указан с помощью IP-адреса; в этом случае значение по умолчанию —''(расширение не отправляется).Сведения о повторном использовании сеансов TLS см. в разделе
Session Resumption.
-
Событие: 'keylog'
-
line<Buffer>Строка текста в кодировке ASCII в формате NSSSSLKEYLOGFILE. -
tlsSocket<tls.TLSSocket>Экземплярtls.TLSSocket, для которого он был создан.
Событие keylog возникает, когда соединение, управляемое этим агентом, генерирует или получает ключевой материал (обычно до завершения рукопожатия, но не обязательно). Этот ключевой материал можно сохранить для отладки, поскольку он позволяет расшифровать перехваченный TLS-трафик. Для каждого сокета событие может возникать несколько раз.
Типичный пример использования — добавление полученных строк в общий текстовый файл, который затем используется программным обеспечением (например, Wireshark) для расшифровки трафика:
// ...
https.globalAgent.on('keylog', (line, tlsSocket) => {
fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 });
});
jscopyКласс: https.Server
- Расширяет:
<tls.Server>
Дополнительные сведения см. в разделе http.Server.
server.close([callback])
-
callback<Function> - Возвращает:
<https.Server>
См. server.close() в модуле node:http.
server[Symbol.asyncDispose]()
Вызывает server.close() и возвращает promise, который выполняется после закрытия сервера.
server.closeAllConnections()
См. server.closeAllConnections() в модуле node:http.
server.closeIdleConnections()
См. server.closeIdleConnections() в модуле node:http.
server.headersTimeout
- Тип:
<number>По умолчанию:60000
См. server.headersTimeout в модуле node:http.
server.listen()
Запускает HTTPS-сервер в режиме ожидания зашифрованных соединений. Этот метод идентичен методу server.listen() класса net.Server.
server.maxHeadersCount
- Тип:
<number>По умолчанию:2000
См. server.maxHeadersCount в модуле node:http.
server.requestTimeout
- Тип:
<number>По умолчанию:300000
См. server.requestTimeout в модуле node:http.
server.setTimeout([msecs][, callback])
-
msecs<number>По умолчанию:120000(2 минуты) -
callback<Function> - Возвращает:
<https.Server>
См. server.setTimeout() в модуле node:http.
server.timeout
- Тип:
<number>По умолчанию: 0 (без ограничения времени ожидания)
См. server.timeout в модуле node:http.
server.keepAliveTimeout
- Тип:
<number>По умолчанию:5000(5 секунд)
См. server.keepAliveTimeout в модуле node:http.
https.createServer([options][, requestListener])
-
options<Object>Принимаетoptionsизtls.createServer(),tls.createSecureContext()иhttp.createServer(). -
requestListener<Function>Обработчик, добавляемый к событию'request'. - Возвращает:
<https.Server>
Модули JavaScript
// 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);
CommonJS
// 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);
Или
Модули JavaScript
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);
CommonJS
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);
Чтобы создать сертификат и ключ для этого примера, выполните команду:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \ -keyout private-key.pem -out certificate.pem bashcopy
Затем, чтобы создать сертификат pfx для этого примера, выполните команду:
openssl pkcs12 -certpbe AES-256-CBC -export -out test_cert.pfx \ -inkey private-key.pem -in certificate.pem -passout pass:sample bashcopy
https.get(options[, callback])
https.get(url[, options][, callback])
-
url<string>|<URL> -
options<Object>|<string>|<URL>Принимает те жеoptions, что иhttps.request(); по умолчанию используется метод GET. -
callback<Function> - Возвращает:
<http.ClientRequest>
Аналог метода http.get(), но для HTTPS.
options может быть объектом, строкой или объектом URL. Если options — строка, она автоматически разбирается с помощью new URL(). Если это объект URL, он автоматически преобразуется в обычный объект options.
Модули JavaScript
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);
});
CommonJS
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
Глобальный экземпляр https.Agent для всех HTTPS-запросов клиента. Отличается от конфигурации https.Agent по умолчанию тем, что keepAlive включён, а значение timeout составляет 5 секунд.
https.request(options[, callback])
https.request(url[, options][, callback])
-
url<string>|<URL> -
options<Object>|<string>|<URL>Принимает всеoptionsизhttp.request(), с некоторыми отличиями в значениях по умолчанию:-
protocolПо умолчанию:'https:' -
portПо умолчанию:443 -
agentПо умолчанию:https.globalAgent
-
-
callback<Function> - Возвращает:
<http.ClientRequest>
Выполняет запрос к защищённому веб-серверу.
Также принимаются следующие дополнительные options из tls.connect(): 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.
Модули JavaScript
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();
CommonJS
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():
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) => {
// ...
});
jscopy
Также можно отказаться от объединения соединений, не используя 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) => {
// ...
});
jscopy
Пример использования объекта URL в качестве options:
const options = new URL('https://abc:xyz@example.com');
const req = https.request(options, (res) => {
// ...
});
jscopy
Пример фиксации отпечатка сертификата или открытого ключа (аналогично pin-sha256):
Модули JavaScript
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();
CommonJS
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();
Например, результат будет таким:
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 textcopy
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/api/https.html