0Pricing
Java Academy · درس

‏JWT: البنية والإنشاء والتحقق

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

‏JWT: البنية والإنشاء والتحقق درس مجاني في Java Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Java Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Java Academy 4 دروس في المجموع.

ما المقصود بـ JWT؟

رمز JSON المميز للويب (JWT) هو تنسيق مدمج وآمن للاستخدام في عناوين URL للرموز المميّزة، ويُستخدم لنقل المطالبات بين الأطراف. يُوقَّع JWT، ويمكن تشفيره اختياريًا. وهو مكتفٍ ذاتيًا، فلا حاجة إلى البحث في قاعدة البيانات للتحقق من المطالبات.

بنية JWT:‏ Header.Payload.Signature

يتكون JWT من ثلاثة أجزاء مشفّرة بترميز Base64URL تفصل بينها نقاط: header.payload.signature. يحدد الرأس الخوارزمية. وتحتوي الحمولة على المطالبات. ويتحقق التوقيع من سلامة البيانات.

// Example JWT:
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9      <- header
// .eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIn0  <- payload
// .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c     <- signature

فك ترميز الرأس والحمولة

فك ترميز كل جزء باستخدام Base64URL لرؤية JSON. تحتوي الحمولة على «claims»، ومنها المطالبات القياسية: sub (الموضوع)، وiss (المُصدِر)، وexp (انتهاء الصلاحية)، وiat (وقت الإصدار).

// Header:
{ "alg": "HS256", "typ": "JWT" }
// Payload:
{ "sub": "user-42", "name": "Alice", "role": "ADMIN",
  "iat": 1716000000, "exp": 1716003600 }

إنشاء JWT يدويًا (HS256)

أنشئ JSON للرأس والحمولة، وشغّل ترميز Base64URL على كل منهما، ثم ادمجهما بنقطة، وبعد ذلك احسب HMAC-SHA256 لـ header.payload وألحقه كتوقيع.

String header  = Base64.getUrlEncoder().withoutPadding()
    .encodeToString("{\"alg\":\"HS256\",\"typ\":\"JWT\"}".getBytes());
String payload = Base64.getUrlEncoder().withoutPadding()
    .encodeToString("{\"sub\":\"user-42\",\"exp\":9999999999}".getBytes());
String sigInput = header + "." + payload;
byte[] sig = computeHmac(secretKey, sigInput);
String jwt = sigInput + "." + Base64.getUrlEncoder().withoutPadding().encodeToString(sig);

التحقق من JWT يدويًا

قسّم الرمز عند النقاط، وفك ترميز الرأس والحمولة، وأعد حساب HMAC على header.payload، ثم قارنه بالتوقيع، وتحقق من أن exp يقع في المستقبل.

String[] parts = jwt.split("\\.");
String sigInput = parts[0] + "." + parts[1];
byte[] expectedSig = computeHmac(secretKey, sigInput);
byte[] actualSig   = Base64.getUrlDecoder().decode(parts[2]);
if (!MessageDigest.isEqual(expectedSig, actualSig)) throw new SecurityException("Invalid signature");
// Decode payload and check exp:
String payloadJson = new String(Base64.getUrlDecoder().decode(parts[1]));
// parse JSON and check exp > now

استخدام مكتبة java-jwt‏ (Auth0)

تُبسّط مكتبة com.auth0:java-jwt إنشاء JWT والتحقق منه باستخدام واجهة برمجية سلسة.

// Create:
Algorithm alg = Algorithm.HMAC256(secretKey);
String token = JWT.create()
    .withSubject("user-42")
    .withClaim("role", "ADMIN")
    .withExpiresAt(Instant.now().plusSeconds(3600))
    .sign(alg);
// Verify:
JWTVerifier verifier = JWT.require(alg).withIssuer("my-service").build();
DecodedJWT decoded = verifier.verify(token);
System.out.println(decoded.getSubject());

‏HS256 مقابل RS256

يستخدم HS256 مفتاحًا متماثلًا مشتركًا؛ وهو بسيط، لكن يجب أن يثق المُصدِر وجهة التحقق كل منهما بالآخر فيما يتعلق بالمفتاح. أما RS256 فيستخدم RSA: التوقيع بالمفتاح الخاص والتحقق بالمفتاح العام؛ وهو مناسب للبنى متعددة الخدمات التي يمكن لأي خدمة فيها إجراء التحقق من دون معرفة مفتاح التوقيع.

تخزين JWT: ملفات تعريف الارتباط HttpOnly مقابل localStorage

خزّن JWT في ملفات تعريف ارتباط HttpOnly (لا يمكن الوصول إليها من JS، مما يمنع سرقتها عبر XSS) مع علامتي Secure وSameSite=Strict. تجنب localStorage، إذ يمكن لهجمات XSS قراءته.

// Set JWT as HttpOnly cookie in Spring:
ResponseCookie cookie = ResponseCookie.from("jwt", token)
    .httpOnly(true).secure(true).sameSite("Strict")
    .path("/").maxAge(3600).build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());

رموز التحديث

تتميز JWT بمدة صلاحية قصيرة (15 دقيقة). أما رموز التحديث (المعتمة والمخزنة على الخادم) فتتمتع بمدة صلاحية أطول. يبادل العميل رمز تحديث برمز JWT جديد من دون إعادة المصادقة.

تحدي إبطال JWT

تتسم JWT بأنها عديمة الحالة، ولا توفر آلية إبطال مدمجة. استخدم مدة صلاحية قصيرة مع قائمة حظر لمعرّفات JWT المُبطلة (مطالبة jti) في Redis لدعم تسجيل الخروج قبل انتهاء الصلاحية.

// On logout, add the jti to a Redis blocklist with TTL = token expiry:
redis.set("revoked:" + jti, "1", ex, 3600);
// On verify, check blocklist:
if (redis.exists("revoked:" + decoded.getId())) throw new SecurityException("Token revoked");

تكامل JWT مع Spring Security

في Spring Security، طبّق JwtAuthenticationFilter extends OncePerRequestFilter لاستخراج JWT والتحقق منه وتعيين SecurityContext منه في كل طلب.

String token = request.getHeader("Authorization").replace("Bearer ","");
DecodedJWT decoded = verifier.verify(token);
String userId = decoded.getSubject();
UsernamePasswordAuthenticationToken auth =
    new UsernamePasswordAuthenticationToken(userId, null, authorities);
SecurityContextHolder.getContext().setAuthentication(auth);

تحقق سريع

ما الفرق البنيوي الأساسي بين توقيع JWT باستخدام HS256 وتوقيعه باستخدام RS256؟

مراجعة

JWT = header.payload.signature (بترميز Base64URL). وقّعه باستخدام HMAC (HS256) أو RSA (RS256). تحقّق من التوقيع ومن المطالبة exp. خزّنه في ملفات تعريف ارتباط HttpOnly. استخدم مدة صلاحية قصيرة مع رموز التحديث. أبطله عبر قائمة حظر jti في Redis.

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

هل درس «‏JWT: البنية والإنشاء والتحقق» مجاني؟

نعم — نص درس «‏JWT: البنية والإنشاء والتحقق» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Java Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Java Academy 4 دروس في المجموع.

ماذا ستتعلم في «‏JWT: البنية والإنشاء والتحقق»؟

فكّ بنية JWT يدويًا، وأنشئ رموزًا موقّعة باستخدام سر، وتحقق من المطالبات دون أطر عمل تتمرن على Java Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Java Academy؟

لا تُشترط خبرة سابقة. Java Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «‏JWT: البنية والإنشاء والتحقق»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Java Academy هذا؟

نعم. كل درس في Java Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. التجزئة التشفيرية باستخدام MessageDigest
  2. التشفير المتماثل باستخدام AES
  3. ‏HMAC-SHA256 لضمان سلامة الرسائل
  4. ‏JWT: البنية والإنشاء والتحقق
← العودة إلى Java Academy