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

رمز JWT (JSON Web Token) هو سلسلة مضغوطة وآمنة للروابط تمثل مجموعة من المعلومات (عادةً عن مستخدم أو جلسة) بطريقة يمكن تمريرها بين الأنظمة. غالبًا ما تراه كقيمة طويلة تبدأ بشيء مثل eyJ...، تُرسل في هيدر HTTP مثل Authorization: Bearer \u003ctoken\u003e.
تُعتمد تسجيلات الدخول التقليدية غالبًا على جلسات الخادم: بعد تسجيل الدخول يخزن الخادم بيانات الجلسة ويعطي المتصفح كوكي مع معرّف الجلسة. كل طلب يتضمن تلك الكوكي، والخادم يبحث عن سجل الجلسة.
مع المصادقة المعتمدة على الرموز، يتجنّب الخادم حفظ حالة لكل طلب مستخدم. بدلاً من ذلك، يحتفظ العميل برمز (مثل JWT) ويضمن إرساله مع استدعاءات API. هذا شائع للواجهات لأنّه:
فرق مهم: "بدون حالة" لا يعني "لا فحوصات من جانب الخادم مطلقًا". العديد من الأنظمة الحقيقية لا تزال تتحقق من الرموز مقابل حالة المستخدم، أو تدوير المفاتيح، أو آليات الإبطال.
تحمل JWTs عادةً دليل المصادقة (أنك مسجّل دخولك) وتلميحات تفويض أساسية (أدوار، أذونات، نطاقات) — لكن يجب على الخادم تطبيق قواعد التفويض صراحة.
غالبًا ما تُستخدم JWTs كـ توكنات وصول في:
JWT هو سلسلة مضغوطة مكوّنة من ثلاثة أجزاء، كلّها مرمّزة بـ base64url ومفصولة بنقاط:
header.payload.signature
مثال (محرّف):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzAwMDAwMDAwfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c…
الهيدر يصف كيف نُشِئَ التوكن — والأهم خوارزمية التوقيع (مثلاً HS256، RS256/ES256) ونوع التوكن.
حقول شائعة:
typ: غالبًا JWT (غالبًا ما يُتجاهل عمليًا)alg: خوارزمية التوقيع المستخدمةkid: معرّف المفتاح لمساعدة المُتحقق في اختيار المفتاح الصحيح أثناء التدويرملاحظة أمنية: لا تثق بالهيدر بشكل أعمى. ضع قائمة مسموح بها للخوارزميات التي تستخدمها فعلًا، ولا تقبل alg: "none".
الحمولة تحوي "claims" (الحقول) عن المستخدم وسياق التوكن: لمن هو مخصّص، من أصدَره، ومتى ينتهي.
مهم: JWTs ليست مشفّرة افتراضيًا. الترميز Base64url يجعل التوكن آمنًا للروابط؛ لكنه لا يخفي البيانات. أي شخص يحصل على التوكن يمكنه فكّ ترميزه وقراءة الهيدر والحمولة.
لذلك تجنب وضع أسرار (كلمات مرور، مفاتيح API) أو بيانات شخصية حساسة داخل JWT.
يُنشأ التوقيع بتوقيع الهيدر + الحمولة باستخدام مفتاح:
التوقيع يوفر السلامة: يمكّن الخادم من التحقق أن التوكن لم يُعدّل وأنه صُدِر بواسطة موثوق. لا يوفر التوقيع السرية.
لأن JWT يتضمّن الهيدر والحمولة في كل طلب يُرسل فيه، الرموز الأكبر تعني استخدام عرض نطاق ترددي أكبر. احرص على تقليل المطالبات وفضّل المعرفات بدل البيانات الثقيلة.
تقع المطالبات عادةً في فئتين: مسجّلة (أسماء قياسية) ومخصّصة (حقول تطبيقك).
iss (الناشر): من أنشأ التوكنsub (الموضوع): من يدور حوله التوكن (غالبًا معرف المستخدم)aud (المتلقي): لمن يُقصَد التوكن (مثلاً API محدد)exp (وقت الانتهاء): متى يجب التوقف عن قبول التوكنiat (وقت الإصدار): متى أُصْدِر التوكنnbf (ليس قبل): لا يُقبل التوكن قبل هذا الوقتأضف فقط ما تحتاجه الخدمة المستقبلة لاتخاذ قرار تفويض.
أمثلة جيدة:
user_id)تجنّب "مطالبات الراحة" التي تكرّر بيانات الملف الشخصي بكثرة؛ فهي تزيد من حجم التوكن، قد تصبح قديمة بسرعة، وتزيد من أثر التسريب.
بما أن الحمولة قابلة للقراءة، لا تخزن:
إن احتجت معلومات حساسة، خزّنها على الخادم وضع مرجعًا فقط (مثل معرف) في التوكن — أو استخدم تنسيقًا مشفّرًا (JWE) عند الاقتضاء.
التوقيع ليس تشفيرًا.
عند إصدار JWT، يوقّع الخادم الهيدر + الحمولة المشفرة. عند تقديم التوكن لاحقًا، يعيد الخادم حساب التوقيع ويقارنه. إذا تغيّر حتى حرف واحد، فستفشل المصادقة ويرفض النظام التوكن.
JWT هو صيغة توكن. OAuth 2.0 وOpenID Connect (OIDC) هي بروتوكولات تصف كيف تطلب التطبيقات وتصدر وتستخدم التوكنات.
OAuth 2.0 يختص في المقام الأول بـ التفويض: السماح لتطبيق بالوصول لواجهة برمجة تطبيقات نيابة عن المستخدم دون مشاركة كلمة المرور.
تكون توكنات الوصول عادةً قصيرة العمر (دقائق). تقصير العمر يحدّ من الضرر في حال تسرب توكن.
يضيف OIDC المصادقة (من هو المستخدم) فوق OAuth 2.0 ويقدّم ID token، والذي عادةً ما يكون JWT.
قاعدة أساسية: لا تستخدم ID token لاستدعاء API.
لمزيد من السياق حول تدفقات عملية، انظر /blog/jwt-authentication-flow.
تبدو عملية نموذجية كالتالي:
المستخدم يسجّل الدخول (بريد/كلمة مرور، SSO، إلخ). إذا نجحت المصادقة، يُنشئ الخادم JWT (غالبًا توكن وصول) بمطالبات أساسية مثل الموضوع والانتهاء.
يوقّع الخادم التوكن ويرجعه إلى العميل (تطبيق الويب، التطبيق المحمول، أو خدمة أخرى).
للنقاط المحمية، يضمن العميل إرسال JWT في هيدر Authorization:
Authorization: Bearer \u003cJWT\u003e
قبل معالجة الطلب، عادةً ما تتحقق الـ API من:
exp (لم تنتهِ)iss (الناشر المتوقع)aud (مقصود لهذه الـ API)إذا نجحت جميع الفحوص، تُعامل الـ API المستخدم كمصدّق وتطبّق قواعد التفويض (مثل أذونات مستوى السجل).
بسبب انحراف ساعات النظام، تسمح كثير من الأنظمة بتحمّل صغير في التوقيت عند التحقق من مطالبات الوقت مثل exp (وأحيانًا nbf). اجعل الانحراف صغيرًا لتجنب تمديد صلاحية التوكن أكثر من المقصود.
خيار التخزين يغيّر من يستطيع سرقته ومدى سهولة إعادة تشغيله.
التخزين في الذاكرة (مُحبذ غالبًا للـ SPAs) يحتفظ بتوكن الوصول في حالة JS. يُمحَى عند التحديث ويقلّل مخاطر "الاستيلاء لاحقًا"، لكن ثغرة XSS يمكنها قراءته أثناء تشغيل الصفحة. اقترن ذلك بتوكنات وصول قصيرة العمر وتدفّق تحديث آمن.
localStorage/sessionStorage مريحان لكن محفوفان بالمخاطر: أي ثغرة XSS يمكنها استخراج التوكنات من التخزين. إذا استخدمتَهما، اعتبر منع XSS أمرًا لا تفاوض عليه (CSP، تصفية المخرجات، نظافة التبعيات) واجعل الرموز قصيرة العمر.
كوكيز آمنة (غالبًا الخيار الأكثر أمانًا للويب) تخزن التوكنات في كوكي HttpOnly حتى لا يقرأها JavaScript — مما يقلّل أثر سرقة التوكن عبر XSS. المقابل هو خطر CSRF لأن المتصفحات تلحق الكوكيز تلقائيًا.
إذا استخدمت الكوكيز، عيّن:
HttpOnlySecure (HTTPS فقط)SameSite=Lax أو SameSite=Strict (قد تحتاج بعض التدفقات إلى SameSite=None; Secure)وفكّر في استخدام رموز CSRF للطلبات التي تغيّر الحالة.
على iOS/Android، خزّن التوكنات في التخزين الآمن للنظام (Keychain / Keystore). تجنّب الملفات النصية أو التفضيلات العادية. إذا كان نموذج التهديد يتضمن أجهزة مُخترَقة (rooted/jailbroken)، افترض أن الاستخراج ممكن واعتمد على توكنات قصيرة العمر وضوابط على الخادم.
قيّد ما يمكن أن يفعله التوكن: استخدم نطاقات/مطالبات محدودة، اجعل توكنات الوصول قصيرة العمر، وتجنّب تضمين بيانات حساسة.
JWTs مريحة، لكن كثيرًا من الحوادث ناتجة عن أخطاء متكررة. عامل الـ JWT كالنقود: من يحصل عليه يستطيع غالبًا إنفاقه.
إذا دام التوكن أيامًا أو أسابيع، فإن التسريب يمنح المهاجم تلك النافذة الكاملة.
فَضّل توكنات وصول قصيرة العمر (دقائق) وجدّدها عبر آلية أكثر أمانًا. إن احتجت لميزة "تذكّرني"، نفّذها بتوكنات تحديث وتحكّمات على الخادم.
التوقيعات الصالحة وحدها لا تكفي. تحقق من iss و**aud، واعتبر مطالبات الوقت مثل exp وnbf** صالحة.
فك الترميز ليس تحققًا. دائمًا تحقّق من التوقيع على الخادم وطبّق قواعد التفويض على الخادم.
تجنّب وضع JWTs في باراميترات الاستعلام. قد تُخزن في تاريخ المتصفح، سجلات الخادم، أدوات التحليلات، أو رؤوس المرجع.
استخدم Authorization: Bearer ... بدلًا من ذلك.
افترض أن المفاتيح والرموز يمكن أن تتسرب. قم بتدوير مفاتيح التوقيع، استخدم kid لدعم تدوير ناعم، وامتلك استراتيجية إبطال (صلاحيات قصيرة + إمكانية تعطيل الحسابات/الجلسات). للمزيد عن أين تخزن JWTs بأمان، انظر /blog/where-to-store-jwts-safely.
JWTs مفيدة، لكنها ليست دائمًا الخيار الأفضل. السؤال الحقيقي: هل تستفيد من توكن مستقل يمكن التحقق منه دون استعلام قاعدة بيانات على كل طلب؟
لتطبيقات الويب التقليدية التي يُهم فيها الإبطال البسيط، تكون جلسات على الخادم مع كوكيز HttpOnly غالبًا أبسط وأكثر أمانًا.
اختر JWT إذا كنت تحتاج تحققًا بدون حالة عبر خدمات ويمكنك المحافظة على توكنات قصيرة العمر.
تجنّب JWT إذا كنت تحتاج إبطالًا فوريًا، تنوي تخزين بيانات حساسة داخل التوكن، أو يمكنك استخدام كوكيز جلسة بلا تعقيد.
تحقق باستخدام المفتاح الصحيح والخوارزمية المتوقعة. ارفض التواقيع غير الصالحة — لا استثناءات.
exp (الانتهاء)تأكد أن التوكن لم تنتهِ صلاحيته.
nbf (ليس قبل)إن وُجد، تأكد أن التوكن لا يُستخدم قبل الأوان.
aud (المتلقي)تأكد أن التوكن مخصّص لواجهة/خدمة الخاص بك.
iss (الناشر)تأكد أن التوكن صادر عن الناشر المتوقع.
تحقق من صيغة التوكن، فرض أقصى حجم، ورفض أنواع مطالبات غير متوقعة لتقليل أخطاء الحواف.
HS256 (مفتاح متماثل): سر مشترك يوقّع ويُتحقق به.
RS256 / ES256 (مفاتيح لا متناظرة): المفتاح الخاص يوقّع؛ المفتاح العام يتحقق.
قاعدة عامة: إذا احتاج أكثر من نظام مستقل للتحقق، فضّل RS256/ES256.
iss، aud، ومعرّف مستخدم فقط إن سمح السياسة).هل JWT مشفّر؟
لا افتراضيًا. معظم JWTs موقعة وليست مشفّرة، ما يعني أن المحتوى يمكن قراءته من أي شخص يملك التوكن. استخدم JWE أو احتفظ بالبيانات الحساسة خارج JWTs.
هل أستطيع إبطال JWT؟
ليس بسهولة إذا كنت تعتمد فقط على توكنات وصول مستقلة ذاتية الحِمل. النهج الشائعة تشمل توكنات وصول قصيرة العمر، قوائم حظر في الحالات عالية المخاطر، أو توكنات تحديث مع تدوير.
كم يجب أن تكون مدة exp؟
قصير قدر الإمكان دون الإضرار بتجربة المستخدم والبنية. كثير من APIs تستخدم دقائق لتوكنات الوصول وترافقها توكنات تحديث للجلسات الأطول.
إذا كنت تنفّذ مصادقة JWT في API أو SPA جديد، فالكثير من العمل متكرر: ربط الميدل وير، التحقق من iss/aud/exp، تعيين أعلام الكوكيز، ومنع تسجيل المعاملات التي تحتوي توكنات.
مع Koder.ai، يمكنك توليد تطبيق ويب (React)، خدمات خلفية (Go + PostgreSQL)، أو تطبيق Flutter عن طريق واجهة محادثة—ثم التكرار في وضع التخطيط، استخدام لقطات واسترجاع عند صقل إعدادات الأمان، وتصدير الشيفرة المصدرية عند الاستعداد. إنها طريقة عملية لتسريع بناء تدفقات مصادقة مبنية على JWT مع تحكّم واضح في منطق التحقق، استراتيجية تدوير المفاتيح، وإعدادات النشر/الاستضافة (بما في ذلك النطاقات المخصّصة).
رمز JWT (JSON Web Token) هو سلسلة مضغوطة وآمنة للروابط تحمل "claims" (حقول بيانات) ويمكن للخادم التحقق منها. عادةً ما تُرسل طلبات API مع الهيدر التالي:
Authorization: Bearer \u003ctoken\u003eالفكرة الأساسية: بإمكان الخادم التحقق من سلامة/أصالة الرمز (عن طريق التوقيع) دون الحاجة لوجود سجل جلسة على الخادم لكل طلب.
المصادقة عبر الجلسات عادةً تخزن حالة الجلسة على الخادم (سجل جلسة مرتبطة بكوكي/معرّف الجلسة). مع المصادقة عبر JWT، يقدّم العميل رمزًا موقّعًا مع كل طلب، وتتحقق الـ API منه.
JWTs شائعة في واجهات برمجة التطبيقات والهياكل متعددة الخدمات لأن التحقق يمكن أن يتم محليًا، ما يقلّل الحاجة لمخزن جلسات مشترك.
مصطلح "بدون حالة" لا يعني بالضرورة "بدون فحوصات على الخادم" — كثير من الأنظمة لا تزال تُجري قوائم إبطال، أو تحقق حالة المستخدم، أو تتعامل مع تدوير المفاتيح.
يتركّب JWT من ثلاثة أجزاء مرمّزة بـ Base64URL ومفصولة بنقاط:
header.payload.signatureالهيدر يصف طريقة التوقيع، الحمولة تحوي المطالبات (مثل sub, exp, aud)، والتوقيع يمكّن الخادم من اكتشاف التلاعب.
لا. JWTs العادية عادةً ما تكون موقّعة وليست مشفّرة.
إذا احتجت للسرية، فكّر في JWE (رموز مشفّرة) أو احتفظ بالبيانات الحساسة على الخادم واستخدم معرّفًا داخل الـ JWT.
التوقيع يسمح للخادم بالتأكد من أن الرمز لم يُغيّر وأنه صُدر بواسطة من يملك مفتاح التوقيع.
لكن التوقيع لا يفعل:
expعامل الرمز كأداة اعتماد: إذا سُرِق يمكن غالبًا إعادة استخدامه حتى ينقضي.
alg يخبر المُتحقق بالخوارزمية المستخدمة (مثل HS256 أو RS256). kid هو مُعرّف المفتاح الذي يساعد في اختيار المفتاح الصحيح أثناء تدوير المفاتيح.
قواعد أمان سريعة:
ابدأ بالمطالبات المسجّلة القياسية وقلّل المطالبات المخصصة.
مطالبات مسجّلة شائعة:
JWT هو صيغة للرموز؛ OAuth 2.0 وOpenID Connect هما بروتوكولات تحدد كيف تطلب التطبيقات وتصدر وتستخدم الرموز.
توزيع نموذجي:
في تطبيقات الويب، الخيارات الشائعة:
إذا استخدمت الكوكيز، عيّن:
بحدٍ أدنى، تحقّق من:
exp (لم تنتهِ صلاحيته)iss (الناشر المتوقع)aud (مخصّص لواجهتك/خدمتك)nbf (إن وجد)أضف ضوابط عملية:
algalg: "none".kid غير الموثوقة تُسبّب سلوكًا غير آمن عند البحث عن المفتاح.iss (الناشر)sub (الموضوع / مُعرّف المستخدم)aud (المستلم المقصود)exp (الانتهاء)iat (وقت الإصدار)nbf (لا يُقبل قبل هذا الوقت)تجنّب وضع أسرار أو بيانات شخصية حساسة في الحمولة لأنها قابلة للقراءة إذا تسرّب الرمز.
قاعدة مهمة: لا تستخدم ID token لاستدعاء API لأن الغرض مختلف.
HttpOnlySecure (HTTPS فقط)SameSite=Lax أو SameSite=Strict (بعض التدفقات عابرة المواقع قد تحتاج SameSite=None; Secure)وفكّر في استخدام رموز CSRF لطلبات تغير الحالة.