Skip to content

HTTPS

[مستقر: 2 - مستقر]

مستقر: 2 الاستقرار: 2 - مستقر

شفرة المصدر: lib/https.js

HTTPS هو بروتوكول HTTP عبر TLS/SSL. في Node.js، يتم تنفيذه كوحدة نمطية منفصلة.

تحديد ما إذا كان دعم التشفير غير متاح

من الممكن إنشاء Node.js دون تضمين دعم وحدة node:crypto. في مثل هذه الحالات، ستؤدي محاولة import من https أو استدعاء require('node:https') إلى ظهور خطأ.

عند استخدام CommonJS، يمكن التقاط الخطأ الذي تم طرحه باستخدام try/catch:

js
let https;
try {
  https = require('node:https');
} catch (err) {
  console.error('https support is disabled!');
}

عند استخدام الكلمة المفتاحية ESM import المعجمية، لا يمكن التقاط الخطأ إلا إذا تم تسجيل معالج لـ process.on('uncaughtException') قبل أي محاولة لتحميل الوحدة (باستخدام، على سبيل المثال، وحدة التحميل المسبق).

عند استخدام ESM، إذا كانت هناك فرصة لتشغيل التعليمات البرمجية على إصدار من Node.js حيث لم يتم تمكين دعم التشفير، ففكر في استخدام الدالة import() بدلاً من الكلمة المفتاحية import المعجمية:

js
let https;
try {
  https = await import('node:https');
} catch (err) {
  console.error('https support is disabled!');
}

صنف: https.Agent

[السجل]

الإصدارالتغييرات
v5.3.0دعم 0 maxCachedSessions لتعطيل تخزين جلسة TLS مؤقتًا.
v2.5.0تمت إضافة المعامل maxCachedSessions إلى options لإعادة استخدام جلسات TLS.
v0.4.5تمت الإضافة في: v0.4.5

كائن Agent لـ HTTPS مشابه لـ http.Agent. راجع https.request() لمزيد من المعلومات.

new Agent([options])

[السجل]

الإصدارالتغييرات
v12.5.0لا تقم بتعيين اسم الخادم تلقائيًا إذا تم تحديد المضيف الهدف باستخدام عنوان IP.
  • options <Object> مجموعة من الخيارات القابلة للتكوين لتعيينها على الوكيل. يمكن أن تحتوي على نفس الحقول الموجودة في http.Agent(options)، و
    • maxCachedSessions <number> الحد الأقصى لعدد جلسات TLS المخزنة مؤقتًا. استخدم 0 لتعطيل تخزين جلسة TLS مؤقتًا. الافتراضي: 100.
    • servername <string> قيمة امتداد إشارة اسم الخادم التي سيتم إرسالها إلى الخادم. استخدم السلسلة الفارغة '' لتعطيل إرسال الامتداد. الافتراضي: اسم مضيف الخادم الهدف، ما لم يتم تحديد الخادم الهدف باستخدام عنوان IP، وفي هذه الحالة يكون الافتراضي هو '' (بدون امتداد). راجع استئناف الجلسة للحصول على معلومات حول إعادة استخدام جلسة TLS.

الحدث: 'keylog'

تمت إضافتها في: v13.2.0, v12.16.0

  • line <Buffer> سطر من نص ASCII، بتنسيق SSLKEYLOGFILE الخاص بـ NSS.
  • 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

راجع server.close() في الوحدة node:http.

server[Symbol.asyncDispose]()

تمت إضافتها في: v20.4.0

[مستقر: 1 - تجريبي]

مستقر: 1 الاستقرار: 1 - تجريبي

يستدعي server.close() ويعيد وعدًا يتحقق عند إغلاق الخادم.

server.closeAllConnections()

تمت إضافتها في: v18.2.0

راجع server.closeAllConnections() في الوحدة node:http.

server.closeIdleConnections()

تمت إضافتها في: v18.2.0

راجع server.closeIdleConnections() في الوحدة node:http.

server.headersTimeout

تمت الإضافة في: الإصدار 11.3.0

راجع server.headersTimeout في الوحدة node:http.

server.listen()

يبدأ خادم HTTPS في الاستماع للاتصالات المشفرة. هذه الطريقة مطابقة لـ server.listen() من net.Server.

server.maxHeadersCount

راجع server.maxHeadersCount في الوحدة node:http.

server.requestTimeout

[سجل التغييرات]

الإصدارالتغييرات
الإصدار 18.0.0تم تغيير المهلة الزمنية الافتراضية للطلب من عدم وجود مهلة إلى 300 ثانية (5 دقائق).
الإصدار 14.11.0تمت الإضافة في: الإصدار 14.11.0

راجع server.requestTimeout في الوحدة node:http.

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

تمت الإضافة في: الإصدار 0.11.2

راجع server.setTimeout() في الوحدة node:http.

server.timeout

[سجل التغييرات]

الإصدارالتغييرات
الإصدار 13.0.0تم تغيير المهلة الزمنية الافتراضية من 120 ثانية إلى 0 (بدون مهلة).
الإصدار 0.11.2تمت الإضافة في: الإصدار 0.11.2
  • <number> افتراضي: 0 (بدون مهلة)

راجع server.timeout في الوحدة node:http.

server.keepAliveTimeout

أُضيف في: الإصدار v8.0.0

  • <number> افتراضي: 5000 (5 ثوانٍ)

راجع server.keepAliveTimeout في وحدة node:http.

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.0يمكن الآن تمرير المعامل url مع كائن options منفصل.
v7.5.0يمكن أن يكون المعامل options كائن URL لـ WHATWG.
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.Agent لجميع طلبات عميل HTTPS. يختلف عن التكوين الافتراضي لـ https.Agent من خلال تمكين keepAlive و timeout لمدة 5 ثوانٍ.

https.request(options[, callback])

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

[السجل]

الإصدارالتغييرات
v22.4.0, v20.16.0يعتمد خيار clientCertEngine على دعم المحرك المخصص في OpenSSL والذي تم إهماله في OpenSSL 3.
v16.7.0, v14.18.0عند استخدام كائن URL، سيتم الآن فك ترميز اسم المستخدم وكلمة المرور اللذين تم تحليلهما بشكل صحيح باستخدام URI.
v14.1.0, v13.14.0يتم الآن قبول خيار highWaterMark.
v10.9.0يمكن الآن تمرير معلمة url مع كائن options منفصل.
v9.3.0يمكن أن تتضمن معلمة options الآن clientCertEngine.
v7.5.0يمكن أن تكون معلمة options كائن WHATWG URL.
v0.3.6تمت الإضافة في: v0.3.6

يجعل الطلب إلى خادم ويب آمن.

يتم أيضًا قبول 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.

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

مثال باستخدام URL كـ options:

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