JSONTech

JWT Tokens Explained: Structure, Security & Decoding

Understand JSON Web Tokens from the inside out. Learn the header, payload, and signature structure, common claims, signing algorithms, and security best practices.

فريق JSONTechFebruary 1, 202510 min read

ما هو JWT؟

رمز الويب JSON (JWT، يُنطق "جوت") هو سلسلة نصية مضغوطة وآمنة لعناوين URL يمثّل المطالبات بين طرفين. وهو الأسلوب الأشيع لمعالجة المصادقة والتفويض في تطبيقات الويب الحديثة.

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

أين تُستخدم رموز JWT

  • المصادقة. بعد تسجيل دخول المستخدم، يصدر الخادم JWT. يخزّنه العميل ويرسله في ترويسة Authorization مع كل طلب.
  • تسجيل الدخول الأحادي (SSO). تسمح رموز JWT للمستخدم بالمصادقة مرة واحدة والوصول إلى خدمات متعددة. تصدر مزوّدو الهوية مثل Auth0 وOkta وKeycloak رموز JWT يمكن للخدمات التالية التحقق منها بشكل مستقل.
  • تفويض واجهات برمجة التطبيقات. تتبادل الخدمات المصغّرة رموز JWT فيما بينها لإثبات أن الطلب أُنجز نيابةً عن مستخدم مُصادَق عليه وبأذونات محددة.
  • تبادل المعلومات. بما أن رموز JWT موقّعة، يمكنها حمل بيانات موثوقة بين الأطراف دون خطوة تحقق إضافية.

الأجزاء الثلاثة لرمز JWT

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

header.payload.signature

فيما يلي JWT حقيقي (مختصر لسهولة القراءة):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

لنفكّك كل جزء.

الجزء 1: الترويسة

تصف الترويسة نوع الرمز وخوارزمية التوقيع. بعد فك الترميز من Base64URL:

{
  "alg": "HS256",
  "typ": "JWT"
}

تُبيّن alg للمُتحقّق أي خوارزمية يستخدم للتحقق من التوقيع. وتؤكد typ أن هذا JWT (وليس JWE أو نوعًا آخر من الرموز).

الجزء 2: الحمولة (المطالبات)

تحتوي الحمولة على المطالبات — أي البيانات التي يحملها الرمز فعليًا. بعد فك الترميز:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

المطالبات أزواج مفتاح–قيمة. بعضها موحّد (يُسمى «المطالبات المسجّلة»)، ويمكنك إضافة مطالبات مخصّصة حسب الحاجة.

تُرمَّز الحمولة بتنسيق Base64URL، ولا تُشفَّر. مَن يملك الرمز يمكنه فك ترميز الحمولة وقراءتها. لا تضع أبدًا أسرارًا أو كلمات مرور أو بيانات شخصية حساسة في حمولة JWT.

الجزء 3: التوقيع

يُحسب التوقيع بأخذ الترويسة المُرمَّزة، ثم نقطة، ثم الحمولة المُرمَّزة، وتوقيع الناتج بمفتاح سري:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

يضمن التوقيع أن الرمز لم يُعرَّض للتلاعب. إن غيّر أحدٌ حرفًا واحدًا في الترويسة أو الحمولة، فلن يطابق التوقيع، وسيرفض المُتحقّق الرمز.

جرّب بنفسك: الصق أي JWT في مُفكّك JWT على JSONTech لفحص الأجزاء الثلاثة فورًا.

مطالبات JWT الشائعة

تحدّد مواصفة JWT (RFC 7519) مجموعة من المطالبات المسجّلة. لا شيء منها إلزامي، لكنها معتمدة على نطاق واسع:

المطالبةالاسم الكاملالوصف
subالموضوعمن يخصّه الرمز (غالبًا معرّف المستخدم)
issالمُصدرالجهة التي أصدرت الرمز (مثل عنوان URL لخادم المصادقة)
audالجمهورالمستلم المقصود (مثل عنوان URL لواجهة برمجة التطبيقات)
expوقت انتهاء الصلاحيةطابع زمني Unix بعده يصبح الرمز غير صالح
iatوقت الإصدارطابع زمني Unix لحظة إنشاء الرمز
nbfغير صالح قبلالرمز غير صالح قبل هذا الطابع الزمني Unix
jtiمعرّف JWTمعرّف فريد لمنع إعادة استخدام الرمز

أما المطالبات المخصّصة فهي أي حقول إضافية تضيفها. من الأمثلة الشائعة role وpermissions وemail وorg_id. اجعل المطالبات المخصّصة قليلة — كل بايت إضافي يُرسل مع كل طلب.

مقارنة خوارزميات التوقيع

يحدّد اختيار الخوارزمية كيف يُنشأ التوقيع ويُتحقَّق منه. فيما يلي الخيارات الثلاثة الأكثر شيوعًا:

الخوارزميةالنوعالمفتاحالأنسب لـ
HS256متماثل (HMAC)سرّ مشترك واحدإعدادات بسيطة يكون فيها المُصدِر والمُتحقّق خدمةً واحدة
RS256غير متماثل (RSA)المفتاح الخاص يوقّع، العام يتحققأنظمة موزّعة، SSO — لا يحتاج المُتحقّق إلى المفتاح الخاص
ES256غير متماثل (ECDSA)المفتاح الخاص يوقّع، العام يتحققمثل RS256 مع مفاتيح أصغر وعمليات أسرع

المتماثل (HS256) أسهل في الإعداد: يشترك المُصدِر والمُتحقّق في السرّ نفسه. العيب أن كل خدمة تحتاج التحقق من الرموز يجب أن تملك السرّ، ما يوسّع سطح الهجوم.

غير المتماثل (RS256، ES256) أنسب للبنى الموزّعة. يوقّع خادم المصادقة الرموز بمفتاح خاص، ويمكن لأي خدمة التحقق بالمفتاح العام المقابل — وهو آمن التوزيع. ES256 خيار حديث: أمان يعادل RS256 مع رموز أصغر وتحقق أسرع.

أفضل الممارسات الأمنية

رموز JWT أداة قوية، لكن سوء استخدامها سهل. التزم بما يلي:

  • لا تُخزِّن الأسرار في الحمولة. الحمولة مُرمَّزة وليست مُشفَّرة. يستطيع أي شخص فك ترميزها. إن احتجت رموزًا مُشفَّرة، فاستخدم JWE (JSON Web Encryption).
  • استخدم أوقات انتهاء قصيرة. يفضّل أن تنتهي صلاحية رموز الوصول خلال 5–15 دقيقة. استخدم رموز التحديث للجلسات الأطول. الرموز قصيرة العمر تحدّ من الضرر إن سُرقت.
  • استخدم HTTPS دائمًا. يمكن اعتراض رموز JWT المرسلة عبر HTTP أثناء النقل. HTTPS أمر لا يُساوم عليه.
  • تحقّق من جميع المطالبات. راجع دائمًا exp وiss وaud. لا تكتفِ بالتحقق من التوقيع — ارفض الرمز المنتهي أو الموجّه خطأً.
  • لا تقبل alg: none. تقبل بعض المكتبات رموزًا غير موقّعة إذا جاءت الترويسة بـ "alg": "none". ارفض هذه الخوارزمية صراحةً في إعدادات المُتحقّق.
  • استخدم قائمةً مسموحًا بها للخوارزميات. اضبط المُتحقّق ليقبل فقط الخوارزمية أو الخوارزميات التي تتوقعها (مثل RS256 فقط). يقي ذلك من هجمات خلط الخوارزميات.
  • خزّن الرموز بأمان. ملفات تعريف الارتباط HttpOnly أكثر أمانًا من localStorage لأنها لا تُتاح لـ JavaScript (ما يخفّف هجمات XSS). إن استخدمت localStorage فافهم المفاضلات.

أخطاء JWT الشائعة

تتكرر هذه الأنماط في مراجعات الأمان:

  • وضع JWT في عنوان URL. تُسجَّل سلاسل الاستعلام في سجلات الخادم وسجل المتصفح وترويسات المُحيل. فضّل ترويسة Authorization أو ملف تعريف ارتباط.
  • عدم التحقق من التوقيع إطلاقًا. يفكّك بعض المطورين الحمولة بمكتبة Base64 ويتخطون التحقق. يعني ذلك أن المهاجم يمكنه تزوير أي رمز.
  • استخدام سرّ ضعيف مع HS256. إن كان السرّ المشترك "secret" أو "password123" فقد يُكسر في ثوانٍ. استخدم سلسلة عشوائية تشفيرية بطول لا يقل عن 256 بت.
  • رموز بلا انتهاء صلاحية. إن لم تتضمّن المطالبة exp، يبقى الرمز صالحًا للأبد. إن تسرّب، لا سبيل لإلغائه دون تغيير مفتاح التوقيع (ما يُبطِل جميع الرموز).
  • تخزين بيانات كثيرة. تُرسل رموز JWT مع كل طلب HTTP. رمز بحجم 4 كيلوبايت يزيد العبء على كل استدعاء لواجهة برمجة التطبيقات. اجعل الحمولة خفيفة.

تدفق تحديث الرمز

تنتهي صلاحية رموز الوصول قصيرة العمر بسرعة، فتحتاج طريقة لإصدار رموز جديدة دون إعادة تسجيل الدخول. هذا هو تدفق رمز التحديث:

  1. يسجّل المستخدم الدخول. يعيد الخادم رمز وصول (قصير العمر، مثل 15 دقيقة) ورمز تحديث (طويل العمر، مثل 7 أيام).
  2. يرسل العميل رمز الوصول مع كل طلب واجهة برمجة تطبيقات في ترويسة Authorization: Bearer.
  3. عند انتهاء صلاحية رمز الوصول، تعيد واجهة برمجة التطبيقات استجابة 401 Unauthorized.
  4. يرسل العميل رمز التحديث إلى نقطة نهاية مخصّصة /refresh.
  5. يتحقق الخادم من رمز التحديث، ويصدر رمز وصول جديدًا (ورمز تحديث جديد اختياريًا — يُسمى تدوير رمز التحديث)، ويعيدهما.
  6. يعيد العميل محاولة الطلب الأصلي برمز الوصول الجديد.

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

// Simplified refresh flow (client-side)
const handleApiRequest = async (url, options) => {
  let response = await fetch(url, {
    ...options,
    headers: {
      ...options.headers,
      Authorization: `Bearer ${getAccessToken()}`,
    },
  });

  if (response.status === 401) {
    const refreshResponse = await fetch("/api/refresh", {
      method: "POST",
      body: JSON.stringify({ refresh_token: getRefreshToken() }),
    });

    if (refreshResponse.ok) {
      const { access_token, refresh_token } = await refreshResponse.json();
      saveTokens(access_token, refresh_token);

      response = await fetch(url, {
        ...options,
        headers: {
          ...options.headers,
          Authorization: `Bearer ${access_token}`,
        },
      });
    } else {
      redirectToLogin();
    }
  }

  return response;
};

رموز JWT مقابل الجلسات: متى تستخدم أيهما

من أكثر المواضيع جدلًا في تطوير الويب. لكل من النهجين حالات استخدام مشروعة:

الجانبJWTجلسات على الخادم
تخزين الحالةالعميل (خادم بلا حالة)الخادم (مخزن جلسات / قاعدة بيانات)
قابلية التوسعسهل — بلا حالة مشتركة بين الخوادميتطلب مخزن جلسات مشتركًا (Redis، قاعدة بيانات)
الإلغاءصعب — يحتاج قائمة حظر أو انتهاء صلاحية قصيرسهل — حذف الجلسة من المخزن
حجم الحمولةأكبر (تحمل المطالبات في كل طلب)أصغر (مجرد ملف تعريف ارتباط لمعرّف الجلسة)
عبر النطاقاتيعمل جيدًا (يُرسل كرمز Bearer)يتطلب إعداد ملفات ارتباط CORS
الخدمات المصغّرةمثالي — كل خدمة تتحقق بشكل مستقلكل خدمة تستعلم مخزن الجلسات
البساطةأجزاء أكثر (توقيع، تدفق التحديث)أبسط للتنفيذ الصحيح

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

استخدم الجلسات عندما تحتاج إلغاءً سهلًا (مثل «تسجيل الخروج من كل الأجهزة»)، أو تدير تطبيقًا أحاديّ البنية، أو تريد أبسط خيار آمن لتطبيق ويب تقليدي.

جرّب بنفسك: فكّ أي JWT وافحصه فورًا عبر مُفكّك JWT على JSONTech — بياناتك لا تغادر متصفحك.

أدوات ذات صلة