رموز JWT في Kotlin: التوليد والتحقق والاستخدام مع io.jsonwebtoken

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

رموز JWT في Kotlin: دليل شامل مع مكتبة jjwt

\n\n

في تطوير الويب الحديث، أصبحت JWT (JSON Web Tokens) معيارًا للمصادقة وتبادل المعلومات بين العميل والخادم. في نظام Kotlin البيئي، خاصة عند إنشاء تطبيقات الخلفية على Spring Boot أو Ktor، غالبًا ما تنشأ الحاجة للعمل مع JWT. في هذه المقالة، سنشرح مكتبة io.jsonwebtoken (jjwt) — الأداة الأكثر شيوعًا للعمل مع JWT في Java/Kotlin.

\n\n

ما هو JWT؟

\n

JWT هي طريقة مضغوطة وآمنة لعناوين URL لتمثيل الادعاءات (claims) بين طرفين. يتكون الرمز من ثلاثة أجزاء مفصولة بنقاط:

\n
    \n
  • Header — الرأس، يحتوي على نوع الرمز وخوارزمية التوقيع (مثل HS256, RS256).
  • \n
  • Payload — الحمولة مع الادعاءات (claims): sub (الموضوع)، iat (وقت الإصدار)، exp (وقت الانتهاء) وبيانات مخصصة.
  • \n
  • Signature — التوقيع، الذي يتم إنشاؤه باستخدام مفتاح سري أو زوج مفاتيح.
  • \n
\n\n

ربط المكتبة

\n

للعمل مع JWT في Kotlin، سنستخدم jjwt (io.jsonwebtoken). أضف التبعية في build.gradle.kts:

\n
dependencies {\n    implementation("io.jsonwebtoken:jjwt-api:0.12.6")\n    runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")\n    runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6") // لتحليل JSON\n}
\n\n

توليد رمز JWT

\n

لإنشاء رمز، يجب تعيين مفتاح سري، وتحديد الادعاءات، وتوقيع الرمز. مثال بلغة Kotlin:

\n
import io.jsonwebtoken.Jwts\nimport io.jsonwebtoken.security.Keys\nimport java.util.Date\nimport javax.crypto.SecretKey\n\nfun generateToken(userId: String, secret: String): String {\n    val key: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray())\n    \n    val now = Date()\n    val expiration = Date(now.time + 3600_000) // +1 ساعة\n    \n    return Jwts.builder()\n        .subject(userId)\n        .issuedAt(now)\n        .expiration(expiration)\n        .claim("role", "USER")\n        .signWith(key)\n        .compact()\n}
\n\n

التحقق من JWT وتحليله

\n

عند استلام رمز من العميل، يجب التحقق من توقيعه وصلاحيته. استخدم Jwts.parser():

\n
import io.jsonwebtoken.JwtException\nimport io.jsonwebtoken.Jwts\nimport io.jsonwebtoken.security.Keys\nimport javax.crypto.SecretKey\n\nfun validateToken(token: String, secret: String): Boolean {\n    return try {\n        val key: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray())\n        Jwts.parser()\n            .verifyWith(key)\n            .build()\n            .parseSignedClaims(token)\n        true\n    } catch (e: JwtException) {\n        false\n    }\n}\n\nfun extractUserId(token: String, secret: String): String? {\n    return try {\n        val key: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray())\n        val claims = Jwts.parser()\n            .verifyWith(key)\n            .build()\n            .parseSignedClaims(token)\n            .payload\n        claims.subject\n    } catch (e: Exception) {\n        null\n    }\n}
\n\n

العمل مع الادعاءات المخصصة

\n

يمكنك إضافة أي بيانات مخصصة إلى الحمولة. على سبيل المثال، تخزين البريد الإلكتروني أو دور المستخدم:

\n
fun generateTokenWithCustomClaims(userId: String, email: String, secret: String): String {\n    val key = Keys.hmacShaKeyFor(secret.toByteArray())\n    \n    return Jwts.builder()\n        .subject(userId)\n        .claim("email", email)\n        .claim("isAdmin", false)\n        .issuedAt(Date())\n        .expiration(Date(System.currentTimeMillis() + 3600_000))\n        .signWith(key)\n        .compact()\n}\n\nfun extractCustomClaim(token: String, secret: String): String? {\n    val key = Keys.hmacShaKeyFor(secret.toByteArray())\n                    

توصيات