Jetons JWT en Kotlin : génération, vérification et utilisation avec io.jsonwebtoken

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Jetons JWT en Kotlin : guide complet avec la bibliothèque jjwt

\n\n

Dans le développement web moderne, les JWT (JSON Web Tokens) sont devenus un standard pour l'authentification et l'échange d'informations entre le client et le serveur. Dans l'écosystème Kotlin, en particulier lors de la création d'applications backend avec Spring Boot ou Ktor, il est souvent nécessaire de travailler avec les JWT. Dans cet article, nous allons explorer la bibliothèque io.jsonwebtoken (jjwt) — l'outil le plus populaire pour travailler avec les JWT en Java/Kotlin.

\n\n

Qu'est-ce que JWT ?

\n

JWT est un moyen compact et sécurisé pour les URL de représenter des revendications (claims) entre deux parties. Le jeton se compose de trois parties séparées par des points :

\n
    \n
  • Header — l'en-tête contenant le type de jeton et l'algorithme de signature (par exemple, HS256, RS256).
  • \n
  • Payload — la charge utile avec les revendications (claims) : sub (sujet), iat (date d'émission), exp (date d'expiration) et des données personnalisées.
  • \n
  • Signature — la signature créée à l'aide d'une clé secrète ou d'une paire de clés.
  • \n
\n\n

Ajout de la bibliothèque

\n

Pour travailler avec les JWT en Kotlin, nous utiliserons jjwt (io.jsonwebtoken). Ajoutez la dépendance dans 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") // pour l'analyse JSON\n}
\n\n

Génération d'un jeton JWT

\n

Pour créer un jeton, vous devez définir une clé secrète, définir les revendications et signer le jeton. Exemple en 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 heure\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

Vérification et analyse d'un JWT

\n

Lors de la réception d'un jeton du client, il est nécessaire de vérifier sa signature et sa date d'expiration. Utilisez 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

Travailler avec des claims personnalisés

\n

Vous pouvez ajouter toutes les données arbitraires dans le payload. Par exemple, stocker l'email ou le rôle de l'utilisateur :

\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                    

Recommendations