Tokens JWT en Java: creación, verificación y uso
JSON Web Token (JWT) es una forma compacta y autónoma de transmitir información entre partes en forma de objeto JSON. En Java, JWT se utiliza activamente para autenticación, autorización e intercambio de datos en API REST y arquitectura de microservicios. En este artículo, analizaremos las dos bibliotecas más populares para trabajar con JWT en Java: JJWT (Java JWT) de Stormpath y java-jwt de Auth0, así como la integración con Spring Security.
¿Qué es JWT y para qué sirve?
JWT consta de tres partes separadas por puntos:
- Header — encabezado que contiene el tipo de token y el algoritmo de firma (por ejemplo, HS256 o RS256).
- Payload — carga útil con declaraciones (claims), como el identificador de usuario, roles y fecha de expiración.
- Signature — firma creada a partir del header, payload y una clave secreta.
En Java, JWT se utiliza principalmente para:
- Autenticación de usuarios sin almacenar sesiones en el servidor (stateless).
- Transmisión de permisos de acceso entre microservicios.
- Tokens de un solo uso para restablecimiento de contraseña o confirmación de correo electrónico.
Biblioteca JJWT (io.jsonwebtoken)
JJWT es la biblioteca más popular para trabajar con JWT en Java. Es fácil de usar, admite todos los algoritmos estándar (HS256, RS256, ES256) y se actualiza activamente.
Inclusión de JJWT mediante Maven
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.12.6</version></dependency><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.12.6</version> <scope>runtime</scope></dependency><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.12.6</version> <scope>runtime</scope></dependency>Creación de un token JWT
import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import io.jsonwebtoken.security.Keys;import javax.crypto.SecretKey;import java.util.Date;
public class JwtExample { public static void main(String[] args) { // Generación de una clave secreta segura para HS256 SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
String token = Jwts.builder() .subject("user123") .claim("role", "admin") .issuedAt(new Date()) .expiration(new Date(System.currentTimeMillis() + 3600000)) // 1 hora .signWith(key) .compact();
System.out.println("JWT creado: " + token); }}Verificación y análisis de JWT
import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jws;import io.jsonwebtoken.JwtException;import io.jsonwebtoken.Jwts;
public class JwtParserExample { public static void main(String[] args) { String jwtToken = "eyJhbGciOiJIUzI1NiJ9..."; // su token SecretKey key = ...; // la misma clave utilizada al crear
try { Jws<Claims> claimsJws = Jwts.parser() .verifyWith(key) .build() .parseSignedClaims(jwtToken);
Claims claims = claimsJws.getPayload(); System.out.println("Subject: " + claims.getSubject()); System.out.println("Role: " + claims.get("role")); System.out.println("Expiration: " + claims.getExpiration()); } catch (JwtException e) { System.out.println("Token no válido: " + e.getMessage()); }