ماذا يعني « فك ترميز JWT »؟
فك ترميز JWT (« jwt decode »، « decode jwt online ») تعني قطع السلسلة عند نقطتين، ثم فك ترميز كل جزء بصيغة Base64URL لاسترجاع JSON الأصلي. لا حاجة لأي مفتاح: الرأس والحمولة مجرد بيانات مُرمَّزة، لا مُشفَّرة. هذه تمامًا الفكرة وراء « jwt payload decoder » أو « decode jwt without verify » — أن ترى ما يحتويه الرمز، دون الدعوى أنه أصيل.
انتبه إلى التمييز الجيد بين الحركتين. القراءة JWT لا يثبت شيئًا: أي شخص يمكنه صنع رمز بحمولة جذابة وتوقيعه بسرّه الخاص. التحقق التوقيع يثبت أن المحتوى لم يُعدَّل بواسطة طرف ثالث. مفكك يعرض « admin: true » بدون تحقق من التوقيع يروي لك قصة، لا حقيقة.
الأجزاء الثلاثة لـ JWT
تُقسَّم السلسلة بالضبط إلى ثلاثة أجزاء تفصلها النقاط: header.payload.signature. يحتوي الرأس في الأقل على alg و typ، وأحيانًا kid للإشارة إلى المفتاح الذي استُخدم. أما الحمولة فتحتوي على claims، وهي أزواج مفتاح-قيمة يدير سجلها IANA. يغطي التوقيع الجزأين الأولين مُتَّلان كما هما — فأي تعديل ولو بحرف واحد يكسر المقارنة.
كل الصعوبة تأتي من أن هذه الأجزاء بصيغة Base64URL لا Base64: علامة الزائد تصبح شرطة، والشرطة المائلة تصبح شرطة سفلية، والحشو = يختفي. لذلك سيفشل مفكك Base64 الكلاسيكي في JWT صالح. جدول « Base64URL مقابل Base64 الكلاسيكي » في تبويب المرجع يوضح هذه الاستبدالات بالضبط.
كيف تتحقق من توقيع: HS256، RS256، ES256
بالنسبة لخوارزمية HMAC — HS256، HS384، HS512 — يُستخدم السر نفسه للتوقيع والتحقق: تعيد الأداة حساب HMAC(secret, base64url(header) + "." + base64url(payload)) وتقارن النتيجة بالتوقيع المرفق. هذا هو الحال الأكثر شيوعًا، والأخطر أيضًا: أي خدمة تملك السر تستطيع إصدار رمز. سر أقل من 32 بايت، معاد استخدامه بين بيئات، يكفي لكسر السلسلة بأكملها.
بالنسبة للخوارزميات غير المتماثلة — RS256، RS384، RS512، ES256، ES384، ES512، PS256 — لا تحتاج إلا إلى المفتاح العام للتحقق، ما يتيح التحقق من رمز صادر عن طرف ثالث دون مشاركة سر توقيعه أبدًا. الصق المفتاح بصيغة PEM -----BEGIN PUBLIC KEY----- (SPKI)؛ الناتج الخام من تصدير OpenSSL قابل للاستخدام مباشرة. في ES256، يكون التوقيع بصيغة r||s الخام، وهي التي يتوقعها WebCrypto.
وأخيرًا، يجب توخي الحذر من alg confusion : إذا كانت خدمتك تتوقع RS256 لكنها تقبل رمزًا يعلن في رأسه HS256، فسيوقّع المهاجم بالمفتاح العام — الذي يصبح مفتاح HMAC — وينجح في التحقق. ثبّت الخوارزمية المتوقعة على الخادم، ولا تقرأها أبدًا من الرمز نفسه.
exp، iat، nbf: الطوابع الزمنية المُضلِّلة
هذه الـ claims الثلاثة هي ثوانٍ Unix، بدون أجزاء من الثانية ومنطقة زمنية: iat عند 1516239022 تعني 2018-01-17T21:30:22Z. خطأان يتكرران باستمرار: المقارنة بتاريخ بالميلي ثانية (قيمة أكبر بعشرة آلاف مرة) وتفسير الطابع الزمني كتوقيت محلي بدل UTC. يحوّل تبويب « انتهاء الصلاحية » في الاتجاهين، ويعرض ISO 8601 والتاريخ المحلي والزمن المتبقي أو المنقضي — لاكتشاف رمز « منتهي بالفعل » فورًا حتى لثانية واحدة.
تمديد مدة الصلاحية لا يرفع مستوى الأمان: exp exp المؤجل يغيّر القيمة المعروضة، وليس التوقيع. إن اضطررت لإعادة الإصدار، فأعد توقيع الرمز بالسر أو المفتاح الخاص — وهذا هو دور تبويب « الترميز ».
Base64URL: لماذا تفشل المفككات الكلاسيكية
يستخدم Base64URL (RFC 4648 §5) الأبجدية A-Z a-z 0-9 - _ ولا يقبل الحشو. حمولة من 20 حرفًا تنتج غالبًا طولًا غير من مضاعفات الأربعة بعد حذف = : وهذا طبيعي وليس تلفًا. الأحرف - و _ غامضة للعين البشرية، وهو ما يفسر نصف « الرموز المعطوبة » التي تُبلَّغ عنها. مفككنا يقبل الأبجدتين، والأحرف المختلطة، والحشو الاختياري، والبادئة Bearer.
الأمان: ما لا يوفّره JWT
JWT لا يضمن السرية ولا الإبطال. الحمولة مقروءة للجميع: لا تضع فيها أبدًا بريدًا إلكترونيًا أو دورًا داخليًا أو بيانات شخصية لا تقبل إرسالها علنًا. ويبقى الرمز الموقّع صالحًا حتى exp بعد تسجيل الخروج — فتحتاج إلى قائمة إبطال، أو jti تتبّعًا من جانب الخادم، أو مدد صلاحية قصيرة مع refresh token. والعادة الجيدة: exp مدة قصيرة (من 10 إلى 15 دقيقة)، iat إبطال مُتحكَّم به، nbf مواءمة مع iat, aud و iss تُتحقَّق من عند الاستلام.
موصى به لـ
مطوّرو back-end وfront-end (OAuth 2.0، OpenID Connect، API REST)، والمُكاملون ومهندسو DevOps (بنية الهوية، JWKS، تدوير المفاتيح)، والمختبرون ومتخترقو الاختبارات (إعادة كتابة claims، alg confusion، انتهاء الصلاحية)، ومديرو الأنظمة (تصحيح خطأ 401 غامض)، والطلاب (فهم Base64URL وWebCrypto)، وكل من يحتاج إلى مفكك JWT عبر الإنترنت سريع وكامل وسري — ويكمّلهمُشفِّر / مُفكِّك Base64، ومُشفِّر / مُفكِّك URL و منسّق JSON.