Tokens JWT en Kotlin: guía completa con la biblioteca jjwt
\n\nEn el desarrollo web moderno, los JWT (JSON Web Tokens) se han convertido en el estándar para la autenticación y el intercambio de información entre el cliente y el servidor. En el ecosistema de Kotlin, especialmente al crear aplicaciones backend con Spring Boot o Ktor, surge a menudo la necesidad de trabajar con JWT. En este artículo, analizaremos la biblioteca io.jsonwebtoken (jjwt), la herramienta más popular para trabajar con JWT en Java/Kotlin.
¿Qué es JWT?
\nJWT es una forma compacta y segura para URL de representar afirmaciones (claims) entre dos partes. El token consta de tres partes separadas por puntos:
\n- \n
- Header — encabezado que contiene el tipo de token y el algoritmo de firma (por ejemplo, HS256, RS256). \n
- Payload — carga útil con las afirmaciones (claims):
sub(sujeto),iat(fecha de emisión),exp(fecha de vencimiento) y datos personalizados. \n - Signature — firma creada con una clave secreta o un par de claves. \n
Inclusión de la biblioteca
\nPara trabajar con JWT en Kotlin usaremos jjwt (io.jsonwebtoken). Agregue la dependencia en build.gradle.kts:
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") // para análisis JSON\n}\n\nGeneración de un token JWT
\nPara crear un token, es necesario definir una clave secreta, establecer las afirmaciones y firmar el token. Ejemplo en Kotlin:
\nimport 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 hora\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\nVerificación y análisis de JWT
\nAl recibir un token del cliente, es necesario verificar su firma y fecha de vencimiento. Use Jwts.parser():
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\nTrabajo con claims personalizados
\nPuede agregar cualquier dato arbitrario al payload. Por ejemplo, almacenar el email o el rol del usuario:
\nfun 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 También en la biblioteca
Trabajo con Kafka en TypeScript: librería KafkaJS y ejemplos
Geolocalización y mapas en PHP: revisión de bibliotecas y herramientas
Fiber para Go: guía completa con ejemplos
Creación de herramientas CLI en Node.js: revisión de los frameworks Commander, Yargs e Inquirer
Procesamiento de imágenes en Kotlin: resize y crop con la biblioteca Kamel