# Introducción a JSON Web Token (JWT)

Las *cookies* llevan tiempo utilizándose para autentificar a los usuarios de Internet; y funcionan muy bien para ciertas aplicaciones. Sin embargo, a veces es necesaria **una mayor flexibilidad**. Aquí entra en juego JSON Web Token, un **nuevo estándar abierto** que están adoptando cada vez más sitios web y aplicaciones importantes. Te explicamos qué es un JWT, cómo funciona y en qué casos se utiliza.

## ¿Qué es un JSON Web Token?

Un JSON Web Token es un *token* de acceso estandarizado en el [RFC 7519](https://tools.ietf.org/html/rfc7519 "RFC 7519") que permite el intercambio seguro de datos entre dos partes. Contiene **toda la información importante** sobre una entidad, lo que implica que no hace falta consultar una base de datos ni que la sesión tenga que guardarse en el servidor (sesión sin estado).

Por este motivo, los JWT son especialmente populares en los procesos de autentificación. Con este estándar es posible cifrar mensajes cortos, dotarlos de información sobre el remitente y demostrar si este cuenta con los **derechos de acceso requeridos**. Los propios usuarios solo entran en contacto con el *token* de manera indirecta: por ejemplo, al introducir el nombre de usuario y la contraseña en una interfaz. La comunicación como tal entre las diferentes aplicaciones se lleva a cabo en el lado del cliente y del servidor.

## ¿Cómo se estructura un JSON Web Token?

Un JWT firmado consta de tres partes, todas ellas codificadas en Base64 y separadas por un punto:

```none
HEADER.PAYLOAD.SIGNATURE
```

¿Qué significan estas tres partes?

### Header

El *header* consta **generalmente de dos valores** y proporciona información importante sobre el *token*. Contiene el tipo de *token* y el algoritmo de la firma y/o cifrado utilizados. Este podría ser un ejemplo de *header* de un JWT:

```none
{ "alg": "HS256", "typ": "JWT" }
```

Siempre se recomienda introducir *JWT* como tipo, que hace referencia al tipo de medio *application/jwt* de la IANA. En el ejemplo anterior, el *header* indica que HMAC-SHA256, abreviado como *HS256*, se utiliza para firmar el *token*. Otros **métodos de cifrado típicos** son RSA, con SHA-256 (*RS256*), y ECDSA, con SHA-256 (*ES256*). No se recomienda prescindir del cifrado, aunque sí se puede especificar *none* si los datos no requieren un nivel de protección alto. Los posibles valores están estandarizados por JSON-Web-Encryption según el [RFC 7516](https://tools.ietf.org/html/rfc7516 "RFC 7516").

En el caso de los JSON Web Tokens complejos firmados o cifrados, también existe el parámetro *cty* para *content type*, que se rellena del mismo modo, con el valor *JWT*. En el resto de casos, este parámetro se omite.

### Payload

El campo *payload* de JSON Web Token contiene la información real que se transmitirá a la aplicación. Aquí se definen algunos estándares que determinan qué datos se transmiten y cómo. La información se proporciona como pares *key/value* (*clave-valor*); las claves se denominan ***claims*** en JWT. Hay tres tipos diferentes de *claims*:

- Los ***claims* registrados** son los que figuran en el [IANA JSON Web Token Claim Register](https://www.iana.org/assignments/jwt/jwt.xhtml "IANA JSON Web Token Claim Register") y cuyo propósito se establece en un estándar. Algunos ejemplos son el emisor del *token* (*iss*, de *issuer*), el dominio de destino (*aud*, de *audience*) y el tiempo de vencimiento (*exp*, de *expiration time*). Se utilizan nombres de *claim* cortos para abreviar el *token* lo máximo posible.
- Los ***claims* públicos** pueden definirse a voluntad, ya que no están sujetos a restricciones. Para que no se produzcan conflictos en la semántica de las claves, es necesario registrar los *claims* públicamente en el JSON Web Token Claim Register de la IANA o asignarles nombres que no puedan coincidir.
- Los ***claims* privados** están destinados a los datos que intercambiamos especialmente con nuestras propias aplicaciones. Si bien los *claims* públicos contienen información como *nombre* o *correo electrónico*, los ***claims* privados son más concretos**. Por ejemplo, suelen incluir datos como *identificación de usuario* o *nombre de departamento*. Al nombrarlos, es importante asegurarse de que no vayan a entrar en conflicto con ningún *claim* registrado o público.

Todos los *claims* son opcionales, por lo que no es obligatorio utilizar todos los *claims* registrados. En general, el *payload* puede contener un número ilimitado de *claims*, aunque es aconsejable **limitar la información del JWT al mínimo**. Cuanto más extenso sea el JWT, más recursos necesitará para la codificación y la descodificación.

Un *payload* podría estructurarse, por lo tanto, de la siguiente manera:

```none
{ "sub": "123", "name": "Alicia", "exp": 30 }
```

### Firma

La firma de un JSON Web Token se crea utilizando la codificación Base64 del *header* y del *payload*, así como el método de firma o cifrado especificado. La estructura viene definida por JSON Web Signature (JWS), un estándar establecido en el [RFC 7515](https://tools.ietf.org/html/rfc7515 "RFC 7515"). Para que la firma sea eficaz, es necesario **utilizar una clave secreta** que solo conozca la aplicación original. Por un lado, la firma verifica que el mensaje no se ha modificado por el camino. Por otro, si el *token* está firmado con una clave privada, también garantiza que el remitente del JWT sea el correcto.

Existen diferentes métodos de firma, dependiendo del nivel de confidencialidad de los datos:

1. **Sin protección**: como hemos mencionado, si los datos no requieren un nivel de protección alto, puede especificarse el valor *none* en el *header*. En este caso, no se genera ninguna firma y el JWT solo constará de *header* y *payload*. Sin esta medida de protección, el *payload* puede leerse como texto en claro una vez descifrado el código Base64 y no se comprueba si el mensaje procede del remitente correcto o si fue modificado al transferirse.
2. **Firma (JWS)**: por lo general, basta con comprobar si los datos provienen del remitente correcto y si han sido modificados. Para ello, se utiliza el esquema JSON Web Signature (JWS), que garantiza que el mensaje no se haya cambiado por el camino y proceda del remitente correcto. Con este procedimiento, el *payload* también puede leerse como texto en claro tras el descifrado de Base64.
3. **Firma (JWS) y cifrado (JWE)**: además de JWS, es posible emplear JSON Web Encryption (JWE). JWE cifra el contenido del *payload*, que luego se firma con JWS. Para descifrar el contenido, se indica una contraseña común o una clave privada. De este modo, el remitente se verifica, el mensaje es confidencial y se autentifica, y el *payload* no puede leerse como texto en claro tras el descifrado de Base64.

El cifrado crea una secuencia de caracteres aparentemente aleatoria:

```none
{ 7WK5T79u5mIzjIXXi2oI9Fglmgivv7RAJ7izyj9tUyQ }
```

Nota En cada uno de los métodos anteriores, es necesario utilizar **también SSL para proteger los datos**.

## ¿Cómo funciona un JSON Web Token?

El inicio de sesión de usuario ejemplifica bien la función del JSON Web Token. Antes de utilizar el JWT, hay que **establecer una clave secreta**. Una vez que el usuario ha introducido correctamente sus credenciales, el JWT se devuelve con la clave y se guarda localmente. La transmisión debe realizarse a través de HTTPS para que los datos estén mejor protegidos.

De esta manera, cada vez que el usuario accede a recursos protegidos, como a una [API](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/application-programming-interface-api/) o a una ruta protegida, el *user agent* utiliza el JWT como parámetro (por ejemplo, *jwt* para peticiones *GET*) o como *header* de autorización (para *POST*, *PUT*, *OPTIONS* y *DELETE*). La **otra parte puede descifrar el JSON Web Token** y ejecutar la solicitud si la verificación se realiza correctamente.

Nota Puesto que el JWT se basa en datos de inicio de sesión, no debe conservarse nunca el *token* más tiempo del necesario ni almacenar ningún dato confidencial en la memoria del navegador.

## ¿En qué casos se utiliza JSON Web Token?

JSON Web Token ofrece varias ventajas en comparación con el método tradicional de autentificación y autorización con *cookies*, por lo que se utiliza en las siguientes situaciones:

1. **Aplicaciones** [**REST**](https://www.ionos.com/es-us/digitalguide/servidores/know-how/rest-la-solucion-http-para-paginas-web/): En las aplicaciones REST, el JWT garantiza la ausencia de estado enviando los datos de autentificación directamente con la petición.
2. [**Intercambio de recursos de origen cruzado**](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/cross-origin-resource-sharing/): JSON Web Token envía información mediante el llamado *cross-origin resource sharing*, lo cual le da una gran ventaja sobre las *cookies*, que no suelen enviarse con este procedimiento.
3. **Uso de varios *frameworks***: JSON Web Token está estandarizado y puede utilizarse una y otra vez. Cuando se emplean múltiples *frameworks*, los datos de autentificación pueden compartirse más fácilmente.

## Ejemplo práctico de JWT

A continuación, con un ejemplo de JWT, te mostramos el aspecto final de un *token*. Retomamos el *header* que mencionamos al principio:

```none
{
	"alg": "HS256",
	"typ": "JWT"
}
```

El *payload* del JSON Web Token podría tener el siguiente aspecto:

```none
{
	"sub": "0123456789",
	"name": "Juan Ejemplo",
	"admin": true
}
```

Para lograr la estructura real del JWT (tres partes separadas por puntos), el *header* y el *payload* deben codificarse con Base64. La codificación del *header* se realizaría del siguiente modo:

```none
base64Header = base64Encode(header)
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
```

Lo mismo debe hacerse para el *payload*:

```none
base64Payload = base64Encode(payload)
// eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
```

Ahora creamos la firma. En el *header*, indicamos que se firme con HMAC-SHA256:

```none
signature = HS256(base64Header + '.' + base64Payload, 'secret')
// dyt0CoTl4WoVjAHI9Q_CwSKhl6d_9rhM3NrXuJttkao
```

Como último paso, estas tres partes deben unirse con puntos entre ellas:

```none
Token = base64Header + '.' + base64Payload + '.' + signature
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.dyt0CoTl4WoVjAHI9Q_CwSKhl6d_9rhM3NrXuJttkao
```

La mayoría de los lenguajes de programación actuales proporcionan bibliotecas para generar JWT, por lo que deja de ser necesaria la conversión manual.


This is a markdown version of: [https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/json-web-token-jwt/](https://www.ionos.com/es-us/digitalguide/paginas-web/desarrollo-web/json-web-token-jwt/) for AI/LLM consumption.