JSON Web Token

JSON Web Token (abreviado JWT) es un estándar abierto basado en JSON propuesto por IETF (RFC 7519) para la creación de tokens de acceso que permiten la propagación de identidad y privilegios o claims en inglés. Por ejemplo, un servidor podría generar un token indicando que el usuario tiene privilegios de administrador y proporcionarlo a un cliente. El cliente entonces podría utilizar el token para probar que está actuando como un administrador en el cliente o en otro sistema.  El token está firmado por la clave del servidor, así que el cliente y el servidor son ambos capaces de verificar que el token es legítimo. Los JSON Web Tokens están diseñados para ser compactos, poder ser enviados en las URLs -URL-safe- y ser utilizados en escenarios de Single Sign-On (SSO). Los privilegios de los JSON Web Tokens puede ser utilizados para propagar la identidad de usuarios como parte del proceso de autenticación entre un proveedor de identidad y un proveedor de servicio, o cualquiera otro tipo de privilegios requeridos por procesos empresariales.[1][2][3][4]

El estándar de JWT se basa en otros estándares basados en JSON JSON Web Signature (RFC 7515) y JSON Web Encryption (RFC 7516)

Estructura

Los JSON Web Tokens generalmente están formados por tres partes: un encabezado o header, un contenido o payload, y una firma o signature[5]​. El encabezado identifica qué algoritmo fue usado para generar la firma y normalmente se ve de la siguiente forma:

header = '{"alg":"HS256","typ":"JWT"}'

HS256 indica que este token está firmado utilizando HMAC-SHA256.

El contenido contiene la información de los privilegios o claims del token:

payload = '{"loggedInAs":"admin","iat":1422779638}'

El estándar sugiere incluir una marca temporal o timestamp en inglés, llamado iat para indicar el momento en el que el token fue creado.

La firma está calculada codificando el encabezamiento y el contenido en base64url,  concatenándose ambas partes con un punto como separador:

key           = 'secretkey'
unsignedToken = encodeBase64Url(header) + '.' + encodeBase64Url(payload)
signature     = HMAC-SHA256(key, unsignedToken) 

En el token,  las tres partes -encabezado, contenido y firma- están concatenadas utilizando puntos de la siguiente forma:

token = encodeBase64Url(header) + '.' + encodeBase64Url(payload) + '.' + encodeBase64Url(signature) # token es: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI 

El token puede ser fácilmente transmitido en entornos HTMLHTTP, siendo similar a estándares basados en XML como SAML. Generalmente los algoritmos de cifrado utilizados son HMAC con SHA-256 (HS256) y firma digital con SHA-256 (RS256).

Uso

La autorización se logra cuando el usuario ingresa sus credenciales con éxito, entonces se genera un JSON Web Token que es retornado al cliente, quien tiene que guardarlo localmente, en vez del modelo tradicional de crear una sesión en el servidor y retornar una cookie.

Siempre que el usuario quiere acceder a una ruta protegida o recurso, el cliente tiene que enviar el JWT, generalmente en el encabezado de Authorization utilizando el esquema Bearer. El contenido del encabezado HTTP se ve de la siguiente forma:

Authorization: Bearer eyJhbGci...<snip>...yu5CSpyHI

Este es un mecanismo de autenticación sin estado - stateless- ya que la sesión del usuario nunca se guarda en el proveedor de identidad o en el proveedor del servicio. Los recursos protegidos siempre comprobaran si existe un JWT válido en cada pedido de acceso. Si el token está presente y es válido, el proveedor del servicio otorga accesos a los recursos protegidos. Como los JWTs contienen toda la información necesaria en sí mismos, se reduce la necesidad de consultar la base de datos u otras fuentes de información múltiples veces. 

Campos estándares

El estándar define los siguientes campos que pueden incluirse en los tokens JWT: 

Código Nombre Descripción
iss Issuer Identifica el proveedor de identidad que emitió el JWT
sub Subject Identifica el objeto o usuario en nombre del cual fue emitido el JWT
aud Audience Identifica la audiencia o receptores para lo que el JWT fue emitido, normalmente el/los servidor/es de recursos (e.g. la API protegida). Cada servicio que recibe un JWT para su validación tiene que controlar la audiencia a la que el JWT está destinado. Si el proveedor del servicio no se encuentra presente en el campo aud, entonces el JWT tiene que ser rechazado
exp Expiration time Identifica la marca temporal luego de la cual el JWT no tiene que ser aceptado. 
nbf Not before Identifica la marca temporal en que el JWT comienza a ser válido. EL JWT no tiene que ser aceptado si el token es utilizando antes de este tiempo. 
iat Issued at Identifica la marca temporal en qué el JWT fue emitido.
jti JWT ID Identificador único del token incluso entre diferente proveedores de servicio.

Los campos siguientes pueden ser utilizados en el encabezado:

Código Nombre Descripción
typ Token type Si está presente, se recomienda utilizar el valor JWT.
cty Content type En casos normales, no es recomendado. En casos de firma o cifrado anidado, debe estar presente y el valor debe ser JWT.
alg Message authentication code algorithm El proveedor de identidad puede elegir libremente el algoritmo para verificar la firma del token, aunque algunos de los algoritmos soportados son inseguros.
Cualquiera de los otros campos introducidos por JWS y JWE.

Implementaciones

Algunas de las implementaciones de JWT que existen: 

Puede encontrarse una lista detallada con las especificaciones de cada implementación en https://jwt.io/#libraries-io

Referencias

  1. cr7, mz. «JSON Web Token (JWT)». tools.ietf.org. Consultado el 14 de noviembre de 2016. 
  2. Sevilleja, Chris. «The Anatomy of a JSON Web Token». Consultado el 8 de mayo de 2015. 
  3. «JSON Web Tokens - jwt.io». jwt.io. Consultado el 8 de mayo de 2015. 
  4. McLean, Tim (31 de marzo de 2015). «Critical vulnerabilities in JSON Web Token libraries». Auth0. Consultado el 29 de marzo de 2016. 
  5. «Introducción a JSON Web Token (JWT)». IONOS Digital Guide. Consultado el 31 de octubre de 2022. 
  6. libjwt on github.com
  7. cljwt on github.com
  8. «dgrijalva/jwt-go». GitHub (en inglés). Consultado el 8 de enero de 2018. 
  9. jwt-dotnet on github.com
  10. Crypt::JWT on cpan.org
  11. JSON-WebToken on github.com
  12. lcobucci/jwt on github.com
  13. «jpadilla/pyjwt». GitHub (en inglés). Consultado el 21 de marzo de 2017. 
  14. ruby-jwt on github.com
  15. frank_jwt on github.com
  16. jwt-scala on github.com
  17. «liquidz/clj-jwt». GitHub (en inglés). Consultado el 28 de abril de 2018. 
  18. «bryanjos/joken». GitHub (en inglés). Consultado el 28 de abril de 2018. 
  19. «artemeff/jwt». GitHub (en inglés). Consultado el 28 de abril de 2018. 
  20. «Web.JWT». hackage.haskell.org. Consultado el 28 de abril de 2018. 
  21. auth0/java-jwt on github.com
  22. «auth0/jwt-decode». GitHub (en inglés). Consultado el 28 de abril de 2018. 
  23. «SkyLothar/lua-resty-jwt». GitHub (en inglés). Consultado el 28 de abril de 2018. 
  24. «jwt-js». npm. Consultado el 28 de abril de 2018. 

Enlaces externos

  • jwt.io @– Sitio web especializado sobre JWT con herramientas y documentación, mantenidos por Auth0
  • jwt tool @– Herramienta JWT en línea y preguntas frecuentes
  • JSON Validator Validar cadena de token web JSON