5 دقيقة

ما هو JWT؟ دليل واضح لرموز JSON Web Tokens

تعرف على مفهوم JWT (JSON Web Token)، كيف تعمل أجزاؤه الثلاثة، أين يُستخدم، ونصائح الأمان الأساسية لتجنب أخطاء الشائع حول التوكنات.

ما هو JWT؟ دليل واضح لرموز JSON Web Tokens

JWT ببساطة

رمز JWT (JSON Web Token) هو سلسلة مضغوطة وآمنة للروابط تمثل مجموعة من المعلومات (عادةً عن مستخدم أو جلسة) بطريقة يمكن تمريرها بين الأنظمة. غالبًا ما تراه كقيمة طويلة تبدأ بشيء مثل eyJ...، تُرسل في هيدر HTTP مثل Authorization: Bearer \u003ctoken\u003e.

لماذا نستخدم توكن من الأساس؟

تُعتمد تسجيلات الدخول التقليدية غالبًا على جلسات الخادم: بعد تسجيل الدخول يخزن الخادم بيانات الجلسة ويعطي المتصفح كوكي مع معرّف الجلسة. كل طلب يتضمن تلك الكوكي، والخادم يبحث عن سجل الجلسة.

مع المصادقة المعتمدة على الرموز، يتجنّب الخادم حفظ حالة لكل طلب مستخدم. بدلاً من ذلك، يحتفظ العميل برمز (مثل JWT) ويضمن إرساله مع استدعاءات API. هذا شائع للواجهات لأنّه:

  • يعمل جيدًا عبر خدمات متعددة (بوابات API، ميكروسيرفيسز)
  • يناسب التطبيقات المحمولة وتطبيقات الصفحة الواحدة (SPAs) التي تستدعي APIs مباشرةً
  • يقلّل الحاجة إلى تخزين جلسة مشترك عبر الخوادم

فرق مهم: "بدون حالة" لا يعني "لا فحوصات من جانب الخادم مطلقًا". العديد من الأنظمة الحقيقية لا تزال تتحقق من الرموز مقابل حالة المستخدم، أو تدوير المفاتيح، أو آليات الإبطال.

المصادقة مقابل التفويض (بعبارات بسيطة)

  • المصادقة تجيب: من أنت؟ (تسجّل دخولك وتثبت هويتك).
  • التفويض يجِيب: ما الذي يُسمح لك بفعله؟ (قراءة فواتير، تعديل مشاريع، الوصول لصفحات الإدارة، إلى آخره.)

تحمل JWTs عادةً دليل المصادقة (أنك مسجّل دخولك) وتلميحات تفويض أساسية (أدوار، أذونات، نطاقات) — لكن يجب على الخادم تطبيق قواعد التفويض صراحة.

أين تظهر JWTs

غالبًا ما تُستخدم JWTs كـ توكنات وصول في:

  • واجهات الويب الخلفية (APIs)
  • تطبيقات الصفحة الواحدة (SPAs)
  • التطبيقات المحمولة
  • الأنظمة التي تستخدم OAuth 2.0 أو OpenID Connect (OIDC)

بنية JWT: الهيدر والحمولة والتوقيع

JWT هو سلسلة مضغوطة مكوّنة من ثلاثة أجزاء، كلّها مرمّزة بـ base64url ومفصولة بنقاط:

header.payload.signature

مثال (محرّف):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…

1) الهيدر

الهيدر يصف كيف نُشِئَ التوكن — والأهم خوارزمية التوقيع (مثلاً HS256، RS256/ES256) ونوع التوكن.

حقول شائعة:

  • typ: غالبًا JWT (غالبًا ما يُتجاهل عمليًا)
  • alg: خوارزمية التوقيع المستخدمة
  • kid: معرّف المفتاح لمساعدة المُتحقق في اختيار المفتاح الصحيح أثناء التدوير

ملاحظة أمنية: لا تثق بالهيدر بشكل أعمى. ضع قائمة مسموح بها للخوارزميات التي تستخدمها فعلًا، ولا تقبل alg: "none".

2) الحمولة

الحمولة تحوي "claims" (الحقول) عن المستخدم وسياق التوكن: لمن هو مخصّص، من أصدَره، ومتى ينتهي.

مهم: JWTs ليست مشفّرة افتراضيًا. الترميز Base64url يجعل التوكن آمنًا للروابط؛ لكنه لا يخفي البيانات. أي شخص يحصل على التوكن يمكنه فكّ ترميزه وقراءة الهيدر والحمولة.

لذلك تجنب وضع أسرار (كلمات مرور، مفاتيح API) أو بيانات شخصية حساسة داخل JWT.

3) التوقيع

يُنشأ التوقيع بتوقيع الهيدر + الحمولة باستخدام مفتاح:

  • HS256: سر مشترك يوقّع ويُتحقق به
  • RS256/ES256: مفتاح خاص يوقّع؛ مفتاح عام يتحقق

التوقيع يوفر السلامة: يمكّن الخادم من التحقق أن التوكن لم يُعدّل وأنه صُدِر بواسطة موثوق. لا يوفر التوقيع السرية.

اعتبارات الحجم

لأن JWT يتضمّن الهيدر والحمولة في كل طلب يُرسل فيه، الرموز الأكبر تعني استخدام عرض نطاق ترددي أكبر. احرص على تقليل المطالبات وفضّل المعرفات بدل البيانات الثقيلة.

الحمولة والمطالبات: ما يمكنك (وما لا يجب) تخزينه

صمّم الادعاءات بثقة
حدد الأدوار، الجمهور، المُصدِّرين، وقواعد انتهاء الصلاحية قبل توليد أي شيفرة.

تقع المطالبات عادةً في فئتين: مسجّلة (أسماء قياسية) ومخصّصة (حقول تطبيقك).

مطالبات مسجّلة شائعة

  • iss (الناشر): من أنشأ التوكن
  • sub (الموضوع): من يدور حوله التوكن (غالبًا معرف المستخدم)
  • aud (المتلقي): لمن يُقصَد التوكن (مثلاً API محدد)
  • exp (وقت الانتهاء): متى يجب التوقف عن قبول التوكن
  • iat (وقت الإصدار): متى أُصْدِر التوكن
  • nbf (ليس قبل): لا يُقبل التوكن قبل هذا الوقت

مطالبات مخصّصة: اجعلها محدودة

أضف فقط ما تحتاجه الخدمة المستقبلة لاتخاذ قرار تفويض.

أمثلة جيدة:

  • معرف مستخدم داخلي ثابت (user_id)
  • مجموعة صغيرة من الأدوار/الأذونات (فقط إن كنت قادرًا على الحفاظ عليها محدثة)
  • معرف مستأجر/منظمة في تطبيقات متعددة المستأجرين

تجنّب "مطالبات الراحة" التي تكرّر بيانات الملف الشخصي بكثرة؛ فهي تزيد من حجم التوكن، قد تصبح قديمة بسرعة، وتزيد من أثر التسريب.

ما الذي يجب ألا تضعه أبداً في حمولة JWT

بما أن الحمولة قابلة للقراءة، لا تخزن:

  • كلمات المرور، مفاتيح API، توكنات التحديث، أو أي قيمة سرية
  • تفاصيل الدفع، أرقام الهوية الحكومية، أو بيانات شخصية حساسة
  • أي شيء لا تريد نسخه من متصفح أو بروكسي أو سجل

إن احتجت معلومات حساسة، خزّنها على الخادم وضع مرجعًا فقط (مثل معرف) في التوكن — أو استخدم تنسيقًا مشفّرًا (JWE) عند الاقتضاء.

كيف يعمل التوقيع (وما الذي يضمنه)

التوقيع ليس تشفيرًا.

  • التوقيع يشبه ختم غلاف الرسالة: يمكن للناس قراءتها، لكن يمكنهم التحقق من أنها لم تُغيّر.
  • التشفير يشبه قفل الصندوق: فقط من يملك المفتاح يمكنه القراءة.

عند إصدار JWT، يوقّع الخادم الهيدر + الحمولة المشفرة. عند تقديم التوكن لاحقًا، يعيد الخادم حساب التوقيع ويقارنه. إذا تغيّر حتى حرف واحد، فستفشل المصادقة ويرفض النظام التوكن.

JWT مقابل OAuth وOpenID Connect وأنواع التوكن

JWT هو صيغة توكن. OAuth 2.0 وOpenID Connect (OIDC) هي بروتوكولات تصف كيف تطلب التطبيقات وتصدر وتستخدم التوكنات.

OAuth 2.0 وتوكنات الوصول/التحديث

OAuth 2.0 يختص في المقام الأول بـ التفويض: السماح لتطبيق بالوصول لواجهة برمجة تطبيقات نيابة عن المستخدم دون مشاركة كلمة المرور.

  • Access token: يُقدّم إلى API لإثبات الإذن؛ قد يكون JWT أو رمزًا غامضًا
  • Refresh token: توكن طويل العمر يُستخدم للحصول على توكنات وصول جديدة

تكون توكنات الوصول عادةً قصيرة العمر (دقائق). تقصير العمر يحدّ من الضرر في حال تسرب توكن.

OpenID Connect (OIDC) وتوكنات الهوية

يضيف OIDC المصادقة (من هو المستخدم) فوق OAuth 2.0 ويقدّم ID token، والذي عادةً ما يكون JWT.

  • ID token: لتأكيد هوية المستخدم لدى تطبيق العميل
  • Access token: لتفويض طلبات الـ API

قاعدة أساسية: لا تستخدم ID token لاستدعاء API.

لمزيد من السياق حول تدفقات عملية، انظر /blog/jwt-authentication-flow.

تدفق مصادقة JWT الشائع

من البناء إلى النشر
انشر واستضف تطبيقك المعتمد على JWT مباشرةً، مع دعم النطاقات المخصصة.

تبدو عملية نموذجية كالتالي:

1) تسجيل الدخول

المستخدم يسجّل الدخول (بريد/كلمة مرور، SSO، إلخ). إذا نجحت المصادقة، يُنشئ الخادم JWT (غالبًا توكن وصول) بمطالبات أساسية مثل الموضوع والانتهاء.

2) إصدار التوكن

يوقّع الخادم التوكن ويرجعه إلى العميل (تطبيق الويب، التطبيق المحمول، أو خدمة أخرى).

3) استدعاءات API

للنقاط المحمية، يضمن العميل إرسال JWT في هيدر Authorization:

Authorization: Bearer \u003cJWT\u003e

4) التحقق

قبل معالجة الطلب، عادةً ما تتحقق الـ API من:

  • التوقيع (السلامة + الناشر الموثوق)
  • exp (لم تنتهِ)
  • iss (الناشر المتوقع)
  • aud (مقصود لهذه الـ API)

إذا نجحت جميع الفحوص، تُعامل الـ API المستخدم كمصدّق وتطبّق قواعد التفويض (مثل أذونات مستوى السجل).

5) ملاحظة سريعة عن انحراف الساعة

بسبب انحراف ساعات النظام، تسمح كثير من الأنظمة بتحمّل صغير في التوقيت عند التحقق من مطالبات الوقت مثل exp (وأحيانًا nbf). اجعل الانحراف صغيرًا لتجنب تمديد صلاحية التوكن أكثر من المقصود.

أين تخزن JWT بأمان

خيار التخزين يغيّر من يستطيع سرقته ومدى سهولة إعادة تشغيله.

تطبيقات المتصفح: الذاكرة مقابل localStorage مقابل الكوكيز

التخزين في الذاكرة (مُحبذ غالبًا للـ SPAs) يحتفظ بتوكن الوصول في حالة JS. يُمحَى عند التحديث ويقلّل مخاطر "الاستيلاء لاحقًا"، لكن ثغرة XSS يمكنها قراءته أثناء تشغيل الصفحة. اقترن ذلك بتوكنات وصول قصيرة العمر وتدفّق تحديث آمن.

localStorage/sessionStorage مريحان لكن محفوفان بالمخاطر: أي ثغرة XSS يمكنها استخراج التوكنات من التخزين. إذا استخدمتَهما، اعتبر منع XSS أمرًا لا تفاوض عليه (CSP، تصفية المخرجات، نظافة التبعيات) واجعل الرموز قصيرة العمر.

كوكيز آمنة (غالبًا الخيار الأكثر أمانًا للويب) تخزن التوكنات في كوكي HttpOnly حتى لا يقرأها JavaScript — مما يقلّل أثر سرقة التوكن عبر XSS. المقابل هو خطر CSRF لأن المتصفحات تلحق الكوكيز تلقائيًا.

إذا استخدمت الكوكيز، عيّن:

  • HttpOnly
  • Secure (HTTPS فقط)
  • SameSite=Lax أو SameSite=Strict (قد تحتاج بعض التدفقات إلى SameSite=None; Secure)

وفكّر في استخدام رموز CSRF للطلبات التي تغيّر الحالة.

التطبيقات المحمولة: استخدم تخزين النظام الآمن

على iOS/Android، خزّن التوكنات في التخزين الآمن للنظام (Keychain / Keystore). تجنّب الملفات النصية أو التفضيلات العادية. إذا كان نموذج التهديد يتضمن أجهزة مُخترَقة (rooted/jailbroken)، افترض أن الاستخراج ممكن واعتمد على توكنات قصيرة العمر وضوابط على الخادم.

أقل صلاحية ممكنة

قيّد ما يمكن أن يفعله التوكن: استخدم نطاقات/مطالبات محدودة، اجعل توكنات الوصول قصيرة العمر، وتجنّب تضمين بيانات حساسة.

أخطاء أمان شائعة تتعلق بـ JWT تجنبها

JWTs مريحة، لكن كثيرًا من الحوادث ناتجة عن أخطاء متكررة. عامل الـ JWT كالنقود: من يحصل عليه يستطيع غالبًا إنفاقه.

1) صلاحيات طويلة جدًا

إذا دام التوكن أيامًا أو أسابيع، فإن التسريب يمنح المهاجم تلك النافذة الكاملة.

فَضّل توكنات وصول قصيرة العمر (دقائق) وجدّدها عبر آلية أكثر أمانًا. إن احتجت لميزة "تذكّرني"، نفّذها بتوكنات تحديث وتحكّمات على الخادم.

2) تخطي فحوص الناشر والمستقبل

التوقيعات الصالحة وحدها لا تكفي. تحقق من iss و**aud، واعتبر مطالبات الوقت مثل exp وnbf** صالحة.

3) الوثوق بالحمولة التي تم فك ترميزها

فك الترميز ليس تحققًا. دائمًا تحقّق من التوقيع على الخادم وطبّق قواعد التفويض على الخادم.

4) الالتباس في الخوارزميات وخلط المفاتيح

  • لا تقبل أي خوارزمية يطالب بها التوكن. ضع قائمة مسموح بها
  • لا تخلط بين المفاتيح المتماثلة (HS256) والمفتاحية العامة/الخاصة (RS256/ES256)
  • قلّل من تأثير الاختراق بفصل المفاتيح حسب البيئة وتدويرها

5) تسريب التوكن عبر عناوين URL، السجلات، والـ referrers

تجنّب وضع JWTs في باراميترات الاستعلام. قد تُخزن في تاريخ المتصفح، سجلات الخادم، أدوات التحليلات، أو رؤوس المرجع.

استخدم Authorization: Bearer ... بدلًا من ذلك.

6) غياب خطة للتدوير أو الإبطال

افترض أن المفاتيح والرموز يمكن أن تتسرب. قم بتدوير مفاتيح التوقيع، استخدم kid لدعم تدوير ناعم، وامتلك استراتيجية إبطال (صلاحيات قصيرة + إمكانية تعطيل الحسابات/الجلسات). للمزيد عن أين تخزن JWTs بأمان، انظر /blog/where-to-store-jwts-safely.

متى تستخدم JWT (ومتى لا تستخدمه)

أنشئ واجهة أمامية جاهزة لـ JWT
أطلق تطبيق React بصفحة واحدة يقوم بتسجيل الدخول، يخزن الرموز بأمان، ويتصل بنقاط نهاية محمية.

JWTs مفيدة، لكنها ليست دائمًا الخيار الأفضل. السؤال الحقيقي: هل تستفيد من توكن مستقل يمكن التحقق منه دون استعلام قاعدة بيانات على كل طلب؟

الحالات المناسبة لاستخدام JWT

  • APIs بلا حالة وعلى نطاق واسع: تحقق محلي (توقيع + انتهاء) دون استعلام جلسة لكل طلب
  • خدمات متعددة / ميكروسيرفيسز: قواعد تحقق مشتركة ومفاتيح عامة
  • SPAs والتطبيقات المحمولة: عملاء يستدعون APIs مباشرةً
  • توكنات وصول قصيرة العمر: يقلل أثر السرقة

متى يكون JWT خيارًا سيئًا

  • تحتاج إبطال فوري: الجلسات أبسط إذا أردت "تسجيل الخروج في كل مكان الآن" دون بنية تحتية إضافية
  • تحتاج حمل بيانات حساسة: JWT العادية موقّعة وليست مشفّرة
  • توكنات طويلة العمر: قيمة عالية وتستحق الحماية الأكثر صرامة

متى تكون كوكيز الجلسة البسيطة أفضل

لتطبيقات الويب التقليدية التي يُهم فيها الإبطال البسيط، تكون جلسات على الخادم مع كوكيز HttpOnly غالبًا أبسط وأكثر أمانًا.

قائمة قرار سريعة

اختر JWT إذا كنت تحتاج تحققًا بدون حالة عبر خدمات ويمكنك المحافظة على توكنات قصيرة العمر.

تجنّب JWT إذا كنت تحتاج إبطالًا فوريًا، تنوي تخزين بيانات حساسة داخل التوكن، أو يمكنك استخدام كوكيز جلسة بلا تعقيد.

قائمة فحص عملية وأسئلة مكررة

قائمة التحقق عند المصادقة (ما يجب فحصه في كل مرة)

  1. التوقيع صالح

تحقق باستخدام المفتاح الصحيح والخوارزمية المتوقعة. ارفض التواقيع غير الصالحة — لا استثناءات.

  1. exp (الانتهاء)

تأكد أن التوكن لم تنتهِ صلاحيته.

  1. nbf (ليس قبل)

إن وُجد، تأكد أن التوكن لا يُستخدم قبل الأوان.

  1. aud (المتلقي)

تأكد أن التوكن مخصّص لواجهة/خدمة الخاص بك.

  1. iss (الناشر)

تأكد أن التوكن صادر عن الناشر المتوقع.

  1. فحوصات منطقية (مستحسن)

تحقق من صيغة التوكن، فرض أقصى حجم، ورفض أنواع مطالبات غير متوقعة لتقليل أخطاء الحواف.

اختيار HS256 مقابل RS256/ES256

  • HS256 (مفتاح متماثل): سر مشترك يوقّع ويُتحقق به.

    • مناسب لـ: تطبيق/API واحد يتحكم به فريق واحد.
    • تحذير: أي مدقق يملك السر يمكنه أيضًا إصدار توكنات.
  • RS256 / ES256 (مفاتيح لا متناظرة): المفتاح الخاص يوقّع؛ المفتاح العام يتحقق.

    • مناسب لـ: عدة خدمات تتحقق من التوكن؛ توزيع المفاتيح العامة دون تمكين التوقيع.
    • ملاحظة تشغيلية: التدوير أكثر أمانًا لأن الموقّع وحده يملك المفتاح الخاص.

قاعدة عامة: إذا احتاج أكثر من نظام مستقل للتحقق، فضّل RS256/ES256.

المراقبة والتسجيل (دون تسريب الرموز)

  • لا تسجل الرموز الخام (الهيدرز، الكوكيز، باراميترات الاستعلام).
  • إذا احتجت للترابط، سجّل بصمة التوكن (مثل هاش) أو بيانات آمنة (iss، aud، ومعرّف مستخدم فقط إن سمح السياسة).
  • راقب الشذوذ: فشل التوقيعات، زيادة في التوكنات المنتهية، أذواق/ناشرين غير عاديين، وأنماط تحديث مريبة.

أسئلة مكررة

هل JWT مشفّر؟

لا افتراضيًا. معظم JWTs موقعة وليست مشفّرة، ما يعني أن المحتوى يمكن قراءته من أي شخص يملك التوكن. استخدم JWE أو احتفظ بالبيانات الحساسة خارج JWTs.

هل أستطيع إبطال JWT؟

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

كم يجب أن تكون مدة exp؟

قصير قدر الإمكان دون الإضرار بتجربة المستخدم والبنية. كثير من APIs تستخدم دقائق لتوكنات الوصول وترافقها توكنات تحديث للجلسات الأطول.

بناء تطبيقات محمية بـ JWT أسرع مع Koder.ai

إذا كنت تنفّذ مصادقة JWT في API أو SPA جديد، فالكثير من العمل متكرر: ربط الميدل وير، التحقق من iss/aud/exp، تعيين أعلام الكوكيز، ومنع تسجيل المعاملات التي تحتوي توكنات.

مع Koder.ai، يمكنك توليد تطبيق ويب (React)، خدمات خلفية (Go + PostgreSQL)، أو تطبيق Flutter عن طريق واجهة محادثة—ثم التكرار في وضع التخطيط، استخدام لقطات واسترجاع عند صقل إعدادات الأمان، وتصدير الشيفرة المصدرية عند الاستعداد. إنها طريقة عملية لتسريع بناء تدفقات مصادقة مبنية على JWT مع تحكّم واضح في منطق التحقق، استراتيجية تدوير المفاتيح، وإعدادات النشر/الاستضافة (بما في ذلك النطاقات المخصّصة).

الأسئلة الشائعة

ما هو JWT، وأين أرسله عادةً؟

رمز JWT (JSON Web Token) هو سلسلة مضغوطة وآمنة للروابط تحمل "claims" (حقول بيانات) ويمكن للخادم التحقق منها. عادةً ما تُرسل طلبات API مع الهيدر التالي:

  • Authorization: Bearer \u003ctoken\u003e

الفكرة الأساسية: بإمكان الخادم التحقق من سلامة/أصالة الرمز (عن طريق التوقيع) دون الحاجة لوجود سجل جلسة على الخادم لكل طلب.

كيف تختلف مصادقة JWT عن جلسات الخادم؟

المصادقة عبر الجلسات عادةً تخزن حالة الجلسة على الخادم (سجل جلسة مرتبطة بكوكي/معرّف الجلسة). مع المصادقة عبر JWT، يقدّم العميل رمزًا موقّعًا مع كل طلب، وتتحقق الـ API منه.

JWTs شائعة في واجهات برمجة التطبيقات والهياكل متعددة الخدمات لأن التحقق يمكن أن يتم محليًا، ما يقلّل الحاجة لمخزن جلسات مشترك.

مصطلح "بدون حالة" لا يعني بالضرورة "بدون فحوصات على الخادم" — كثير من الأنظمة لا تزال تُجري قوائم إبطال، أو تحقق حالة المستخدم، أو تتعامل مع تدوير المفاتيح.

ما هي الأجزاء الثلاثة لـ JWT (الهيدر، الحمولة، التوقيع)؟

يتركّب JWT من ثلاثة أجزاء مرمّزة بـ Base64URL ومفصولة بنقاط:

  • header.payload.signature

الهيدر يصف طريقة التوقيع، الحمولة تحوي المطالبات (مثل sub, exp, aud)، والتوقيع يمكّن الخادم من اكتشاف التلاعب.

هل JWT مشفر، وهل يمكن للناس قراءة ما بداخله؟

لا. JWTs العادية عادةً ما تكون موقّعة وليست مشفّرة.

  • التوقيع يضمن التكامل والأصالة (لم يتم تغييره وأًصدره موقّع من جهة موثوقة).
  • أي شخص يحصل على الرمز يمكنه فكّ ترميزه Base64URL وقراءة الهيدر والحمولة.

إذا احتجت للسرية، فكّر في JWE (رموز مشفّرة) أو احتفظ بالبيانات الحساسة على الخادم واستخدم معرّفًا داخل الـ JWT.

ماذا يضمن توقيع JWT — وماذا لا يضمن؟

التوقيع يسمح للخادم بالتأكد من أن الرمز لم يُغيّر وأنه صُدر بواسطة من يملك مفتاح التوقيع.

لكن التوقيع لا يفعل:

  • إخفاء محتوى الحمولة
  • إثبات أن المستخدم ما زال نشطًا (إلا إذا تحققت من ذلك صراحة على الخادم)
  • إبطال الرمز قبل انتهاء exp

عامل الرمز كأداة اعتماد: إذا سُرِق يمكن غالبًا إعادة استخدامه حتى ينقضي.

ما معنى `alg` و `kid` في هيدر JWT، ولماذا هما مهمان؟

alg يخبر المُتحقق بالخوارزمية المستخدمة (مثل HS256 أو RS256). kid هو مُعرّف المفتاح الذي يساعد في اختيار المفتاح الصحيح أثناء تدوير المفاتيح.

قواعد أمان سريعة:

  • ضع قائمة مسموح بها للخوارزميات المتوقعة؛ لا تقبل أي alg عشوائي.
  • لا تقبل alg: "none".
  • لا تدع قيمة kid غير الموثوقة تُسبّب سلوكًا غير آمن عند البحث عن المفتاح.
ما المطالبات التي ينبغي أن أضعها في حمولة JWT؟

ابدأ بالمطالبات المسجّلة القياسية وقلّل المطالبات المخصصة.

مطالبات مسجّلة شائعة:

  • iss (الناشر)
  • sub (الموضوع / مُعرّف المستخدم)
  • aud (المستلم المقصود)
  • exp (الانتهاء)
  • iat (وقت الإصدار)
  • nbf (لا يُقبل قبل هذا الوقت)

تجنّب وضع أسرار أو بيانات شخصية حساسة في الحمولة لأنها قابلة للقراءة إذا تسرّب الرمز.

كيف ترتبط JWT وOAuth 2.0 وOpenID Connect (توكنات الوصول مقابل توكنات الهوية)؟

JWT هو صيغة للرموز؛ OAuth 2.0 وOpenID Connect هما بروتوكولات تحدد كيف تطلب التطبيقات وتصدر وتستخدم الرموز.

توزيع نموذجي:

  • Access token: يُستخدم لاستدعاء API (قد يكون JWT أو رمزًا غامضًا).
  • ID token (OIDC): لتأكيد هوية المستخدم لدى تطبيق العميل (غالبًا JWT).
  • Refresh token: للحصول على توكنات وصول جديدة (غالبًا غامض وحساس للغاية).

قاعدة مهمة: لا تستخدم ID token لاستدعاء API لأن الغرض مختلف.

أين يجب أن أخزن JWT بأمان في تطبيق متصفح؟

في تطبيقات الويب، الخيارات الشائعة:

  • في الذاكرة: يفضّل للـ SPA أحيانًا. يختفي عند التحديث ويقلّل فرص السّرقة لاحقًا، لكن XSS النشط يمكنه قراءته.
  • localStorage/sessionStorage: مريح لكن أي ثغرة XSS قد تسرق الرموز. إذا استخدمت ذلك، اعتبر منع XSS أمرًا حتميًا (CSP، تصفية المخرجات، إدارة التبعيات) واستخدم توكنات قصيرة العمر.
  • كوكيز HttpOnly آمنة: غالبًا الأكثر أمانًا على الويب لأن JS لا يمكنه قراءتها — لكنها تعرضك لمخاطر CSRF لأن المتصفحات ترسل الكوكيز تلقائيًا.

إذا استخدمت الكوكيز، عيّن:

  • HttpOnly
  • Secure (HTTPS فقط)
  • SameSite=Lax أو SameSite=Strict (بعض التدفقات عابرة المواقع قد تحتاج SameSite=None; Secure)

وفكّر في استخدام رموز CSRF لطلبات تغير الحالة.

ما الفحوصات التي يجب أن تُجريها واجهتي البرمجية عند التحقق من JWT؟

بحدٍ أدنى، تحقّق من:

  • التوقيع (باستخدام المفتاح الصحيح والخوارزمية المسموح بها)
  • exp (لم تنتهِ صلاحيته)
  • iss (الناشر المتوقع)
  • aud (مخصّص لواجهتك/خدمتك)
  • nbf (إن وجد)

أضف ضوابط عملية:

  • فرض أقصى حجم للرمز
  • رفض أنواع مطالبات غير متوقعة
  • السماح بتحمّل زمني صغير (clock skew) لتفادي مشاكل تزامن الساعات

Related posts