JWT tokens in Kotlin: generation, verification, and usage with io.jsonwebtoken

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

JWT tokens in Kotlin: complete guide with the jjwt library



In modern web development, JWT (JSON Web Tokens) have become the standard for authentication and information exchange between client and server. In the Kotlin ecosystem, especially when building backend applications with Spring Boot or Ktor, the need to work with JWT often arises. In this article, we will explore the io.jsonwebtoken (jjwt) library — the most popular tool for working with JWT in Java/Kotlin.



What is JWT?

JWT is a compact, URL-safe way to represent claims between two parties. The token consists of three parts separated by dots:

  • Header — contains the token type and signing algorithm (e.g., HS256, RS256).
  • Payload — contains the claims: sub (subject), iat (issued at), exp (expiration time), and custom data.
  • Signature — created using a secret key or a key pair.


Adding the library

To work with JWT in Kotlin, we will use jjwt (io.jsonwebtoken). Add the dependency to build.gradle.kts:

dependencies {    implementation("io.jsonwebtoken:jjwt-api:0.12.6")    runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")    runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6") // for JSON parsing}


Generating a JWT token

To create a token, you need to specify a secret key, set claims, and sign the token. Example in Kotlin:

import io.jsonwebtoken.Jwtsimport io.jsonwebtoken.security.Keysimport java.util.Dateimport javax.crypto.SecretKey

fun generateToken(userId: String, secret: String): String { val key: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray()) val now = Date() val expiration = Date(now.time + 3600_000) // +1 hour return Jwts.builder() .subject(userId) .issuedAt(now) .expiration(expiration) .claim("role", "USER") .signWith(key) .compact()}


Verifying and parsing JWT

When receiving a token from the client, you need to verify its signature and expiration. Use Jwts.parser():

import io.jsonwebtoken.JwtExceptionimport io.jsonwebtoken.Jwtsimport io.jsonwebtoken.security.Keysimport javax.crypto.SecretKey

fun validateToken(token: String, secret: String): Boolean { return try { val key: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray()) Jwts.parser() .verifyWith(key) .build() .parseSignedClaims(token) true } catch (e: JwtException) { false }}

fun extractUserId(token: String, secret: String): String? { return try { val key: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray()) val claims = Jwts.parser() .verifyWith(key) .build() .parseSignedClaims(token) .payload claims.subject } catch (e: Exception) { null }}


Working with custom claims

You can add any arbitrary data to the payload. For example, store the user's email or role:

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

fun extractCustomClaim(token: String, secret: String): String? { val key = Keys.hmacShaKeyFor(secret.toByteArray())

Recommendations