كيفية استخدام متغيرات البيئة في JavaScript الصِرف وبدائلها العملية

دقائق القراءة: 5

مقدمة: هل يمكن استخدام متغيرات البيئة في VanillaJS؟

عند تطوير تطبيقات الويب، تظهر الحاجة إلى إخفاء بعض القيم الحساسة مثل مفاتيح API أو رموز الوصول Access Tokens. في أطر العمل الحديثة مثل React وVue، يبدو التعامل مع متغيرات البيئة أمراً معتاداً، لكن الوضع يختلف عند استخدام VanillaJS مباشرة في المتصفح.

في هذا المقال ستتعرف إلى مفهوم متغيرات البيئة في JavaScript، ولماذا لا يمكن الاعتماد عليها بالطريقة التقليدية داخل تطبيقات الواجهة الأمامية المبنية بـ VanillaJS، كما سنستعرض حلاً عملياً لتمرير المفاتيح أثناء النشر باستخدام Netlify.

شرح احترافي لمتغيرات البيئة في جافاسكربت الصرف وآلية استخدامها مع خدمات النشر

ما هي متغيرات البيئة في JavaScript؟

متغيرات البيئة هي قيم خارجية تُستخدم للتحكم في سلوك التطبيق وفقاً لبيئة التشغيل، مثل بيئة التطوير development أو بيئة الإنتاج production. وغالباً ما تُستخدم لتخزين بيانات حساسة أو متغيرة، مثل:

  • مفاتيح API
  • عناوين الخوادم
  • إعدادات التفعيل أو التعطيل
  • رموز المصادقة Authentication Tokens

الفكرة الأساسية هي فصل القيم الحساسة عن الشيفرة البرمجية نفسها، بحيث لا تُكتب مباشرة داخل الملفات التي قد تُرفع إلى المستودعات العامة مثل GitHub.

لماذا تُستخدم متغيرات البيئة مع طلبات API؟

عند الاتصال بواجهة برمجية تتطلب التحقق من الهوية، يكون من الشائع إرسال مفتاح أو رمز وصول ضمن ترويسة Authorization. المثال التالي يوضح شكلاً شائعاً لطلب باستخدام fetch():

const apiCall = () => {
  fetch(url, {
    headers: {
      Authorization: `bearer ${private_api_key}`
    }
  })
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => JSON.stringify(err))
}

في هذا السيناريو، يصبح تخزين قيمة private_api_key داخل الشيفرة بشكل مباشر ممارسة غير آمنة، خصوصاً إذا كان المشروع عاماً أو قابلاً للوصول من المتصفح.

كيف تُنشأ ملفات .env عادةً؟

في المشاريع المعتمدة على Node.js، يمكن إنشاء ملف باسم .env داخل المجلد الجذر للمشروع، ثم وضع القيم الحساسة بداخله. بعد ذلك، يتم تجاهل هذا الملف عبر .gitignore حتى لا يتتبعه Git.

مثال تقريبي على القيم التي قد يحتويها الملف:

API_KEY=bgrtyaqQtyfadV0F08BHGvfsgskl
TOPIC_ID=F08BHGvfsgsklgrtyaqQtyfadV0F08

وعند التشغيل في بيئة Node.js، يمكن الوصول إلى هذه القيم عبر الكائن process.env.

const env = {
  env_variable: "bgrtyaqQtyfadV0F08BHGvfsgskl",
  topic_id: "F08BHGvfsgsklgrtyaqQtyfadV0F08"
}

console.log(process.env.env_variable)
// prints bgrtyaqQtyfadV0F08BHGvfsgskl to the console

لماذا لا تعمل متغيرات البيئة مباشرة في VanillaJS؟

المشكلة الجوهرية أن VanillaJS في الواجهة الأمامية تعمل داخل المتصفح، وليس داخل بيئة Node.js. لذلك لا يتوفر الكائن العام process.env بشكل افتراضي في المتصفح.

وهذا يعني أنك قد تنشئ ملف .env، لكنك لن تتمكن من استخدامه مباشرة داخل شيفرة العميل بالطريقة المعتادة في تطبيقات الخادم أو المشاريع المبنية بأدوات تجميع حديثة.

الفرق بين React وVanillaJS في هذه النقطة

في مشاريع React، تبدو متغيرات البيئة وكأنها تعمل في الواجهة الأمامية، لكن السبب الحقيقي هو وجود أدوات بناء وتجميع تعتمد على Node.js، والتي تقوم بحقن هذه القيم أثناء عملية البناء build.

أما عند استخدام VanillaJS فقط، فلن تحصل على هذا السلوك تلقائياً، لأن المشروع لا يمر غالباً بنفس سلسلة المعالجة.

هل يمكن الاعتماد على حزمة dotenv؟

يظن بعض المطورين أن تثبيت حزمة dotenv سيحل المشكلة مباشرة، لكنها في الأصل مصممة للعمل في بيئات تدعم Node.js وتوفّر process.env.

عند محاولة استخدامها في شيفرة تعمل في المتصفح، ستظهر مشكلة مثل عدم تعريف require:

require("dotenv").config()

const apiCall = () => {
  fetch(url, {
    headers: {
      Authorization: `bearer ${process.env.env_variable}`
    }
  })
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => JSON.stringify(err))
}

السبب هنا أن dotenv يعتمد على بيئة تشغيل لا يوفرها المتصفح بشكل مباشر. صحيح أن هناك حلولاً إضافية باستخدام أدوات مثل RequireJS أو غيرها، لكنها تزيد التعقيد في مشروع بسيط يعتمد على VanillaJS.

متى تصبح المشكلة أكثر حساسية؟

في بعض الواجهات البرمجية العامة، قد لا تحتاج إلا إلى طلبات GET بسيطة بدون مفتاح خاص. لكن توجد خدمات أخرى، مثل بعض واجهات GitHub أو Twitter، تشترط إرسال مفتاح أو رمز وصول قبل قبول الطلب.

على سبيل المثال، تتطلب واجهة GitHub GraphQL API رمز وصول صالحاً لإتمام الطلبات. وإذا قمت بإضافة هذا الرمز مباشرة إلى المشروع ثم رفعته إلى GitHub، فقد يتم إبطاله أو حذفه لأسباب أمنية.

وهنا تظهر المشكلة العملية: قد يعمل التطبيق محلياً في وضع development، لكنه يتوقف بعد النشر إلى production إذا لم تعد المفاتيح متاحة أثناء البناء أو التشغيل.

حل عملي: تمرير المفتاح أثناء البناء عبر Netlify

إذا كنت تنشر مشروعك على Netlify، فبإمكانك الاستفادة من إعدادات البناء والنشر Build & Deploy لإنشاء ملف إعدادات يحتوي على المفتاح أثناء عملية البناء، من دون وضعه مباشرة في تاريخ المستودع.

الصورة التالية توضح مكان إعدادات البناء في Netlify:

واجهة إعدادات البناء والنشر في Netlify لاستخدام مفاتيح API أثناء عملية النشر

أمر البناء لإنشاء ملف config.js

إذا كان لديك مجلد باسم js داخل المشروع، يمكنك استخدام أمر البناء التالي:

cd js && echo -e "const TOKEN = 'api-token';\n\nexport default TOKEN;" > config.js

هذا الأمر ينشئ ملفاً جديداً باسم config.js داخل مجلد js أثناء عملية البناء، ويضع بداخله قيمة الرمز.

أما إذا كانت ملفات المشروع موجودة في المجلد الجذر مباشرة، فيمكن استخدام الأمر التالي:

echo -e "const TOKEN = 'api-token';\n\nexport default TOKEN;" > config.js

محتوى الملف الناتج

const TOKEN = 'api-token';
export default TOKEN;

كيفية استيراد المفتاح داخل المشروع

بعد إنشاء ملف config.js، يمكنك استيراد القيمة في ملفات JavaScript الأخرى باستخدام import. لكن حتى يعمل هذا الأسلوب، يجب تعريف وسم script على أنه من النوع module.

<script src="./index.js" type="module"></script>

وبذلك تستطيع داخل ملفك البرمجي استيراد الرمز من config.js ثم استخدامه في طلبات API.

ملاحظات أمنية مهمة قبل اعتماد هذا الأسلوب

رغم أن هذه الطريقة عملية لتجاوز مشكلة حذف المفاتيح من المستودع أو منع ظهورها في سجل الالتزامات commit history، فإنها ليست حلاً أمنياً كاملاً.

  • أي مفتاح يصل إلى المتصفح يمكن اكتشافه عبر أدوات المطور DevTools.
  • لا يناسب هذا الأسلوب المفاتيح عالية الحساسية.
  • يمكن استخدامه فقط إذا كانت مخاطر كشف المفتاح محدودة.
  • الحل الأكثر أماناً هو تمرير الطلبات الحساسة عبر خادم وسيط backend بدلاً من كشف المفتاح في الواجهة الأمامية.

أفضل الممارسات عند التعامل مع مفاتيح API في الواجهة الأمامية

  1. لا تضع المفاتيح الحساسة مباشرة داخل ملفات المشروع العامة.
  2. استخدم ملف .gitignore لمنع تتبع الملفات الخاصة.
  3. إذا كان المشروع يعتمد على VanillaJS فقط، ففكر في خادم وسيط للتعامل مع العمليات الحساسة.
  4. استخدم إعدادات البناء في منصات النشر عند الحاجة إلى حلول مؤقتة أو محدودة المخاطر.
  5. راجع سياسات مزود API لمعرفة حدود الاستخدام، ومخاطر تسريب المفاتيح، وآليات الحماية المتاحة.

مقارنة سريعة بين الخيارات المتاحة

الأسلوب هل يعمل مع VanillaJS؟ مستوى الأمان ملاحظات
استخدام .env مباشرة في المتصفح لا منخفض جداً المتصفح لا يدعم process.env افتراضياً
استخدام dotenv في الواجهة الأمامية ليس عملياً منخفض يتطلب بيئة أو أدوات إضافية
إنشاء ملف config.js أثناء البناء نعم متوسط إلى منخفض مفيد للمشاريع البسيطة والمفاتيح غير الحساسة
استخدام backend وسيط نعم الأعلى الخيار الأفضل للإنتاج الحقيقي

الخلاصة التقنية

استخدام متغيرات البيئة في VanillaJS ليس مباشراً لأن المتصفح لا يوفّر process.env مثل Node.js. وإذا كنت بحاجة إلى تمرير مفتاح API في مشروع بسيط، فقد يكون إنشاء ملف إعدادات أثناء البناء عبر Netlify حلاً عملياً ومؤقتاً. لكن من منظور تقني وأمني، يبقى الخيار الأفضل دائماً هو إبقاء المفاتيح الحساسة في جهة الخادم وعدم كشفها للعميل تحت أي ظرف.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *