Json Web Token es un conjunto de medios de seguridad para peticiones http y así representar demandas para ser transferidos entre dos partes (cliente y servidor). Las partes de un JWT se codifican como un objeto JSON que está firmado digitalmente utilizando JSON Web Signature( JWS ).
¿Por qué utilizar Json Web Token?
La mayoría de las aplicaciones actuales consumen servicios rest y están alojadas en distintos dominios con lo cuál no podemos trabajar con sesiones ya que se almacenan en este.
Podemos decir que la mejor alternativa es llevar a cabo la autenticación haciendo uso de tokens que vayan del servidor al cliente, un usuario hace login (no necesita enviar token porque no lo tiene), una vez el servidor de ok retorna un token cómo respuesta y el usuario debe enviar dicho token en las siguientes peticiones para poder acceder a los recursos del servicio.
En cada petición el servidor debe comprobar el token proporcionado por el usuario y si es correcto podrá acceder a los recursos solicitados, de otra forma deberá denegar la petición.
También nos añade más seguridad. Al no utilizar cookies para almacenar la información del usuario, podemos evitar ataques CSRF (Cross-Site Request Forgery) que manipulen la sesión que se envía al backend. Por supuesto podemos hacer que el token expire después de un tiempo lo que le añade una capa extra de seguridad.
El formato de un JWT está compuesto por 3 strings
separados por un punto .
algo así como:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NGE4Y2U2MThlOTFiMGIxMzY2NWUyZjkiLCJpYXQiOiIxNDI0MTgwNDg0IiwiZXhwIjoiMTQyNTM5MDE0MiJ9.yk4nouUteW54F1HbWtgg1wJxeDjqDA_8AhUPyjE5K0U
Cada string
significa una cosa:
- Header La primera parte es la cabecera del token, que a su vez tiene otras dos partes, el tipo, en este caso un JWT y la codificación utilizada. Comunmente es el algoritmo HMAC SHA256, El contenido sin codificar es el siguiente:
{
"alg": "HS256",
"typ": "JWT"
}
Su codificación sería: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- Payload EL Payload está compuesto por los llamados JWT Claims donde irán colocados la atributos que definen nuestro token. Exiten varios que puedes consultar aquí, los más comunes a utilizar son:
sub
: Identifica el sujeto del token, por ejemplo un identificador de usuario.iat
: Identifica la fecha de creación del token, válido para si queremos ponerle una fecha de caducidad. En formato de tiempo UNIXexp
: Identifica a la fecha de expiración del token. Podemos calcularla a partir deliat
. También en formato de tiempo UNIX.
{
"sub": "54a8ce618e91b0b13665e2f9",
"iat": "1424180484",
"exp": "1425390142"
}
Su codificación sería: eyJzdWIiOiI1NGE4Y2U2MThlOTFiMGIxMzY2NWUyZjkiLCJpYXQiOiIxNDI0MTgwNDg0IiwiZXhwIjoiMTQyNTM5MDE0MiJ9
También podemos añadirle más campos, incluso personalizados, como pueden ser el rol del usuario, etc.
{
"sub": "54a8ce618e91b0b13665e2f9",
"iat": "1424180484",
"exp": "1425390142",
"role": 2
}
- Signature La firma es la tercera y última parte del JSON Web Token. Está formada por los anteriores componentes (Header y Payload) cifrados en Base64 con una clave secreta (almacenada en nuestro backend). Así sirve de Hash para comprobar que todo está bien.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload), secret
);
Su codificación sería: yk4nouUteW54F1HbWtgg1wJxeDjqDA_8AhUPyjE5K0U
Por tanto, todo nuestro JSON Web Token, una vez codificado tendrá esta pinta:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NGE4Y2U2MThlOTFiMGIxMzY2NWUyZjkiLCJpYXQiOiIxNDI0MTgwNDg0IiwiZXhwIjoiMTQyNTM5MDE0MiJ9.yk4nouUteW54F1HbWtgg1wJxeDjqDA_8AhUPyjE5K0U
Que si lo comprobamos en la web JWT.io vemos que nos lo traduce a los campos que hemos visto.