0Pricing
Java Academy · Lección

JWT: estructura, creación y verificación

Decodifique manualmente la estructura de un JWT, cree tokens firmados con un secreto y verifique sus claims sin frameworks.

JWT: estructura, creación y verificación es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.

¿Qué es un JWT?

JSON Web Token (JWT) es un formato compacto y seguro para URL que permite transmitir claims entre partes. Un JWT está firmado y, opcionalmente, cifrado. Es autocontenido: no se necesita consultar ninguna base de datos para verificar los claims.

Estructura de un JWT: Header.Payload.Signature

Un JWT tiene tres partes codificadas con Base64URL y separadas por puntos: header.payload.signature. El encabezado especifica el algoritmo. La carga útil contiene los claims. La firma verifica la integridad.

// Example JWT:
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9      <- header
// .eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIn0  <- payload
// .SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c     <- signature

Encabezado y carga útil decodificados

Decodifique cada parte con Base64URL para ver el JSON. La carga útil contiene «claims»; algunos estándar son: sub (sujeto), iss (emisor), exp (expiración) y iat (fecha de emisión).

// Header:
{ "alg": "HS256", "typ": "JWT" }
// Payload:
{ "sub": "user-42", "name": "Alice", "role": "ADMIN",
  "iat": 1716000000, "exp": 1716003600 }

Creación manual de un JWT (HS256)

Construya el JSON del encabezado y de la carga útil, codifique cada uno con Base64URL, concaténelos con un punto, calcule después el HMAC-SHA256 de header.payload y añádalo como firma.

String header  = Base64.getUrlEncoder().withoutPadding()
    .encodeToString("{\"alg\":\"HS256\",\"typ\":\"JWT\"}".getBytes());
String payload = Base64.getUrlEncoder().withoutPadding()
    .encodeToString("{\"sub\":\"user-42\",\"exp\":9999999999}".getBytes());
String sigInput = header + "." + payload;
byte[] sig = computeHmac(secretKey, sigInput);
String jwt = sigInput + "." + Base64.getUrlEncoder().withoutPadding().encodeToString(sig);

Verificación manual de un JWT

Separe el token por los puntos, decodifique el encabezado y la carga útil, vuelva a calcular el HMAC de header.payload, compárelo con la firma y compruebe que exp sea una fecha futura.

String[] parts = jwt.split("\\.");
String sigInput = parts[0] + "." + parts[1];
byte[] expectedSig = computeHmac(secretKey, sigInput);
byte[] actualSig   = Base64.getUrlDecoder().decode(parts[2]);
if (!MessageDigest.isEqual(expectedSig, actualSig)) throw new SecurityException("Invalid signature");
// Decode payload and check exp:
String payloadJson = new String(Base64.getUrlDecoder().decode(parts[1]));
// parse JSON and check exp > now

Uso de la biblioteca java-jwt (Auth0)

La biblioteca com.auth0:java-jwt simplifica la creación y verificación de JWT mediante una API fluida.

// Create:
Algorithm alg = Algorithm.HMAC256(secretKey);
String token = JWT.create()
    .withSubject("user-42")
    .withClaim("role", "ADMIN")
    .withExpiresAt(Instant.now().plusSeconds(3600))
    .sign(alg);
// Verify:
JWTVerifier verifier = JWT.require(alg).withIssuer("my-service").build();
DecodedJWT decoded = verifier.verify(token);
System.out.println(decoded.getSubject());

HS256 frente a RS256

HS256 utiliza una clave simétrica compartida: es sencillo, pero tanto el emisor como el verificador deben confiarse mutuamente la clave. RS256 utiliza RSA: firma con la clave privada y verifica con la clave pública; es adecuado para arquitecturas con varios servicios, donde cualquier servicio puede verificar sin conocer la clave de firma.

Almacenamiento de JWT: cookies HttpOnly frente a localStorage

Almacene los JWT en cookies HttpOnly (no accesibles desde JS, lo que evita su robo mediante XSS) con las marcas Secure y SameSite=Strict. Evite localStorage, ya que los ataques XSS pueden leerlo.

// Set JWT as HttpOnly cookie in Spring:
ResponseCookie cookie = ResponseCookie.from("jwt", token)
    .httpOnly(true).secure(true).sameSite("Strict")
    .path("/").maxAge(3600).build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());

Tokens de actualización

Los JWT tienen una expiración corta (15 minutos). Los tokens de actualización (opacos y almacenados en el servidor) tienen una expiración más larga. El cliente intercambia un token de actualización por un JWT nuevo sin volver a autenticarse.

Desafío de revocación de JWT

Los JWT no tienen estado, por lo que no incluyen un mecanismo de revocación integrado. Utilice una expiración corta y una lista de bloqueo de los identificadores de JWT revocados (claim jti) en Redis para permitir cerrar sesión antes de que expiren.

// On logout, add the jti to a Redis blocklist with TTL = token expiry:
redis.set("revoked:" + jti, "1", ex, 3600);
// On verify, check blocklist:
if (redis.exists("revoked:" + decoded.getId())) throw new SecurityException("Token revoked");

Integración de JWT con Spring Security

En Spring Security, implemente JwtAuthenticationFilter extends OncePerRequestFilter para extraer, verificar y establecer el SecurityContext a partir del JWT en cada solicitud.

String token = request.getHeader("Authorization").replace("Bearer ","");
DecodedJWT decoded = verifier.verify(token);
String userId = decoded.getSubject();
UsernamePasswordAuthenticationToken auth =
    new UsernamePasswordAuthenticationToken(userId, null, authorities);
SecurityContextHolder.getContext().setAuthentication(auth);

Comprobación rápida

¿Cuál es la diferencia estructural clave entre la firma JWT HS256 y la RS256?

Resumen

JWT = header.payload.signature (Base64URL). Firme con HMAC (HS256) o RSA (RS256). Verifique la firma y el claim exp. Almacénelo en cookies HttpOnly. Utilice una expiración corta y tokens de actualización. Revoque los tokens mediante una lista de bloqueo de jti en Redis.

Preguntas frecuentes

¿La lección «JWT: estructura, creación y verificación» es gratis?

Sí — el texto completo de «JWT: estructura, creación y verificación» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.

¿Qué aprenderé en «JWT: estructura, creación y verificación»?

Decodifique manualmente la estructura de un JWT, cree tokens firmados con un secreto y verifique sus claims sin frameworks. Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Java Academy?

No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «JWT: estructura, creación y verificación»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Java Academy?

Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Hash criptográfico con MessageDigest
  2. Cifrado simétrico AES
  3. HMAC-SHA256 para la integridad de mensajes
  4. JWT: estructura, creación y verificación
← Volver a Java Academy