ملفات تعريف الارتباط مقابل localStorage مقابل sessionStorage
عند بناء تطبيق ويب، غالبًا ما تحتاج إلى تخزين بيانات على جانب العميل—سواء كانت تفضيل سمة المستخدم، أو سلة تسوق، أو رمز مصادقة. الخيارات الثلاثة الرئيسية هي الكوكيز وlocalStorage وsessionStorage. لكل منها خصائص مميزة تجعلها مناسبة لسيناريوهات مختلفة. اختيار الخيار الخاطئ قد يؤدي إلى ثغرات أمنية أو مشكلات في الأداء أو تجربة مستخدم سيئة.
تشرح هذه المقالة الفروق، وتقدم إرشادات عملية، وتساعدك على تحديد آلية التخزين التي يجب استخدامها لمشروعك القادم.
مقارنة سريعة
قبل الخوض في التفاصيل، إليك نظرة عامة عالية المستوى على أنواع التخزين الثلاثة:
| الميزة | الكوكيز | localStorage | sessionStorage |
|---|---|---|---|
| السعة | ~4KB لكل نطاق | ~5-10MB لكل أصل | ~5-10MB لكل أصل |
| الاستمرارية | انتهاء صلاحية قابل للتكوين | حتى المسح الصريح | حتى إغلاق التبويب/النافذة |
| يُرسل إلى الخادم | تلقائيًا مع كل طلب HTTP | لا | لا |
| يمكن الوصول إليه عبر JavaScript | نعم (إلا إذا كان HttpOnly) | نعم | نعم |
| النطاق | النطاق والمسار | الأصل (البروتوكول + النطاق + المنفذ) | الأصل + التبويب/النافذة |
| عرضة لـ XSS | نعم (إن لم يكن HttpOnly) | نعم | نعم |
| عرضة لـ CSRF | نعم (إذا استُخدمت للمصادقة) | لا | لا |
الكوكيز: التخزين الأصلي من جانب العميل
الكوكيز موجودة منذ الأيام الأولى للويب. هي قطع صغيرة من البيانات (بحد أقصى ~4KB) يخزنها المتصفح ويرسلها تلقائيًا إلى الخادم مع كل طلب HTTP إلى نفس النطاق.
متى تستخدم الكوكيز
- جلسات المصادقة: خزّن معرّفات الجلسة أو الرموز التي يحتاج الخادم للتحقق منها في كل طلب. استخدم علامات
HttpOnlyوSecureوSameSiteللتخفيف من مخاطر XSS وCSRF. - التخصيص من جانب الخادم: عندما يحتاج الخادم لمعرفة تفضيلات المستخدم (مثل اللغة، السمة) قبل عرض الصفحة.
- التتبع والتحليلات: يمكن للكوكيز الاستمرار عبر الجلسات ومشاركتها بين النطاقات الفرعية إذا تم تكوينها.
اعتبارات الأمان
يتم إرسال الكوكيز تلقائيًا، مما يجعلها عرضة لـ CSRF إذا استُخدمت للمصادقة دون حمايات إضافية. اضبط دائمًا سمة SameSite (Lax أو Strict) وفكّر في استخدام رموز CSRF. للبيانات الحساسة، استخدم HttpOnly لمنع وصول JavaScript، مما يقلل من تأثير XSS.
مثال على تعيين كوكي آمن في استجابة HTTP:
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=3600
localStorage: تخزين مفتاح-قيمة دائم
يوفر localStorage مخزن مفتاح-قيمة بسيط يستمر حتى بعد إغلاق المتصفح. تُخزَّن البيانات لكل أصل (البروتوكول + النطاق + المنفذ) ولا تُرسل إلى الخادم تلقائيًا. مثالي لتخزين البيانات غير الحساسة التي يجب أن تبقى بعد إعادة تحميل الصفحة وإعادة تشغيل المتصفح.
متى تستخدم localStorage
- تفضيلات المستخدم: السمة (داكن/فاتح)، حجم الخط، اللغة، أو إعدادات التخطيط.
- التخزين المؤقت: خزّن استجابات API أو البيانات الثابتة لتقليل طلبات الشبكة وتحسين تجربة عدم الاتصال.
- الحالة من جانب العميل: محتويات سلة التسوق، بيانات النماذج المؤقتة، أو أعلام الميزات.
اعتبارات الأمان
يمكن الوصول إلى localStorage عبر JavaScript، لذا أي ثغرة XSS يمكن أن تكشف جميع البيانات المخزنة. لا تخزّن أبدًا معلومات حساسة مثل كلمات المرور أو أرقام الهوية الشخصية أو رموز المصادقة إلا إذا كانت لديك حمايات XSS قوية. إذا كان لا بد من تخزين الرموز، فكّر في استخدام نهج كوكي HttpOnly بدلاً من ذلك.
مثال على استخدام localStorage:
// Save user preference
localStorage.setItem('theme', 'dark');
// Retrieve preference
const theme = localStorage.getItem('theme');
// Remove item
localStorage.removeItem('theme');
sessionStorage: تخزين لكل تبويب
sessionStorage مشابه لـ localStorage لكن بعمر أقصر: تُمسح البيانات عند إغلاق التبويب أو النافذة. نطاقه تبويب واحد، لذا لا تُشارَك البيانات بين التبويبات أو النوافذ، حتى لنفس الأصل.
متى تستخدم sessionStorage
- النماذج متعددة الخطوات: خزّن بيانات النموذج مؤقتًا بينما يتقدم المستخدم عبر الخطوات، دون استمرارها بعد الإكمال.
- حالة تبويب واحد: بيانات لا يجب أن تتسرب بين التبويبات، مثل حالة مصادقة مؤقتة أو رمز لمرة واحدة.
- العمليات الحساسة: عندما تريد مسح البيانات تلقائيًا عند إغلاق المستخدم للتبويب، مما يقلل التعرض.
اعتبارات الأمان
مثل localStorage، sessionStorage عرضة لـ XSS. ومع ذلك، فإن عمره المحدود ونطاقه لكل تبويب يقللان من فرصة المهاجمين. ومع ذلك، تجنب تخزين بيانات حساسة للغاية.
مثال على استخدام sessionStorage:
// Save form data
sessionStorage.setItem('formStep1', JSON.stringify({name: 'John'}));
// Retrieve form data
const step1 = JSON.parse(sessionStorage.getItem('formStep1'));
كيف تختار: دليل القرار
استخدم القائمة المرتبة التالية لتوجيه قرارك:
- هل يحتاج الخادم لقراءة البيانات في كل طلب؟ إذا نعم، استخدم الكوكيز. مثال: معرّفات الجلسة.
- هل تحتاج البيانات للاستمرار عبر جلسات المتصفح؟ إذا نعم، استخدم localStorage. مثال: تفضيلات المستخدم.
- هل يجب أن تكون البيانات محدودة بتبويب واحد؟ إذا نعم، استخدم sessionStorage. مثال: بيانات النماذج متعددة الخطوات.
- هل البيانات حساسة؟ تجنب تخزينها في localStorage أو sessionStorage. استخدم كوكيز HttpOnly للرموز، ولا تخزّن كلمات المرور أبدًا.
- هل البيانات كبيرة؟ الكوكيز محدودة بـ ~4KB؛ يوفر localStorage وsessionStorage سعة أكبر بكثير.
أفضل ممارسات الأمان
- تحقق دائمًا من المدخلات ونظّفها لمنع XSS، الذي يمكن أن يخترق أي تخزين من جانب العميل.
- استخدم كوكيز HttpOnly وSecure وSameSite لرموز المصادقة للتخفيف من XSS وCSRF.
- تجنب تخزين البيانات الحساسة في localStorage أو sessionStorage. إذا كان لا بد، شفّرها واستخدم انتهاء صلاحية قصير.
- نفّذ سياسة أمان المحتوى (CSP) لتقليل مخاطر XSS.
- امسح البيانات القديمة بانتظام لتجنب الوصول إلى حدود التخزين وتقليل التعرض.
الأسئلة الشائعة
هل يمكنني استخدام localStorage لرموز المصادقة؟
لا يُنصح بذلك لأن localStorage يمكن الوصول إليه عبر JavaScript، مما يجعل الرموز عرضة لـ XSS. فضّل كوكيز HttpOnly مع علامات Secure وSameSite.
ماذا يحدث لـ sessionStorage عند تكرار تبويب؟
عند تكرار تبويب، يحصل التبويب الجديد على نسخة من sessionStorage من التبويب الأصلي في لحظة التكرار. بعد ذلك، يصبحان مستقلين.
هل تُرسل الكوكيز إلى الخادم في كل طلب؟
نعم، تُضمَّن كوكيز النطاق الحالي تلقائيًا في كل طلب HTTP، مما قد يؤثر على الأداء إذا خزّنت الكثير من البيانات. استخدمها باعتدال.
هل تحتاج إلى تنسيق أو التحقق من بيانات JSON التي تخزنها بسرعة؟ جرّب JSON Formatter لتجميل وتصحيح حمولات JSON قبل حفظها في تخزين العميل.