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!')
}

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

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

js
let https
try {
  https = await import('node:https')
} catch (err) {
  console.error('تم تعطيل دعم https!')
}

فئة: 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، بتنسيق NSS SSLKEYLOGFILE.
  • 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

تمت الإضافة في: v11.3.0

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

server.listen()

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

server.maxHeadersCount

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

server.requestTimeout

[السجل]

الإصدارالتغييرات
v18.0.0تغير وقت انتهاء صلاحية الطلب الافتراضي من عدم وجود وقت انتهاء صلاحية إلى 300 ثانية (5 دقائق).
v14.11.0تمت الإضافة في: v14.11.0

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

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

تمت الإضافة في: v0.11.2

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

server.timeout

[السجل]

الإصدارالتغييرات
v13.0.0تغير وقت الانتهاء الافتراضي من 120 ثانية إلى 0 (بدون وقت انتهاء صلاحية).
v0.11.2تمت الإضافة في: v0.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])

[History]

الإصدارالتغييرات
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

[History]

الإصدارالتغييرات
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])

[History]

الإصدارالتغييرات
v22.4.0, v20.16.0يعتمد خيار clientCertEngine على دعم المحرك المخصص في OpenSSL وهو أمر مُهمل في OpenSSL 3.
v16.7.0, v14.18.0عند استخدام كائن URL ، سيتم الآن فك ترميز اسم المستخدم وكلمة المرور المُحلّلين بشكل صحيح.
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) {
    // تأكد من أن الشهادة صادرة إلى المضيف الذي نتصل به
    const err = checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // تثبيت المفتاح العام، مشابه لتثبيت HPKP pin-sha256
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'خطأ في التحقق من الشهادة: ' + `المفتاح العام لـ '${cert.subject.CN}' ` + 'لا يتطابق مع بصمتنا المثبتة'
      return new Error(msg)
    }

    // تثبيت الشهادة الدقيقة، بدلاً من المفتاح العام
    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 = 'خطأ في التحقق من الشهادة: ' + `الشهادة لـ '${cert.subject.CN}' ` + 'لا تتطابق مع بصمتنا المثبتة'
      return new Error(msg)
    }

    // هذه الحلقة للإعلام فقط.
    // اطبع بصمات الشهادة والمفتاح العام لجميع الشهادات في السلسلة. من الشائع تثبيت المفتاح العام للجهة المصدرة على الإنترنت العام، بينما يتم تثبيت المفتاح العام للخدمة في البيئات الحساسة.
    let lastprint256
    do {
      console.log('اسم المضيف الشائع للموضوع:', cert.subject.CN)
      console.log('  بصمة SHA256 للشهادة:', cert.fingerprint256)

      const hash = createHash('sha256')
      console.log('  بصمة المفتاح العام 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('كل شيء على ما يرام. تطابق الخادم الشهادة أو المفتاح العام المثبت لدينا')
  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) {
    // تأكد من أن الشهادة صادرة إلى المضيف الذي نتصل به
    const err = tls.checkServerIdentity(host, cert)
    if (err) {
      return err
    }

    // تثبيت المفتاح العام، مشابه لتثبيت HPKP pin-sha256
    const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8='
    if (sha256(cert.pubkey) !== pubkey256) {
      const msg =
        'خطأ في التحقق من الشهادة: ' + `المفتاح العام لـ '${cert.subject.CN}' ` + 'لا يتطابق مع بصمتنا المثبتة'
      return new Error(msg)
    }

    // تثبيت الشهادة الدقيقة، بدلاً من المفتاح العام
    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 = 'خطأ في التحقق من الشهادة: ' + `الشهادة لـ '${cert.subject.CN}' ` + 'لا تتطابق مع بصمتنا المثبتة'
      return new Error(msg)
    }

    // هذه الحلقة للإعلام فقط.
    // اطبع بصمات الشهادة والمفتاح العام لجميع الشهادات في السلسلة. من الشائع تثبيت المفتاح العام للجهة المصدرة على الإنترنت العام، بينما يتم تثبيت المفتاح العام للخدمة في البيئات الحساسة.
    do {
      console.log('اسم المضيف الشائع للموضوع:', cert.subject.CN)
      console.log('  بصمة SHA256 للشهادة:', cert.fingerprint256)

      hash = crypto.createHash('sha256')
      console.log('  بصمة المفتاح العام 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('كل شيء على ما يرام. تطابق الخادم الشهادة أو المفتاح العام المثبت لدينا')
  console.log('statusCode:', res.statusCode)

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

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

المخرجات للمثال:

text
اسم المضيف الشائع للموضوع: github.com
  بصمة SHA256 للشهادة: 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
  بصمة المفتاح العام ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
اسم المضيف الشائع للموضوع: Sectigo ECC Domain Validation Secure Server CA
  بصمة SHA256 للشهادة: 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
  بصمة المفتاح العام ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
اسم المضيف الشائع للموضوع: USERTrust ECC Certification Authority
  بصمة SHA256 للشهادة: 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
  بصمة المفتاح العام ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
اسم المضيف الشائع للموضوع: AAA Certificate Services
  بصمة SHA256 للشهادة: 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
  بصمة المفتاح العام ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
كل شيء على ما يرام. تطابق الخادم الشهادة أو المفتاح العام المثبت لدينا
statusCode: 200