https://d226lax1qjow5r.cloudfront.net/blog/blogposts/jwts-just-what-are-they/what-are-jwts.png

Los JWT: ¿Qué son?

Publicado el September 28, 2023

Tiempo de lectura: 7 minutos

Uno de los principios por los que se rige el equipo de Experiencia del Desarrollador a la hora de escribir tutoriales es que nunca se debe nunca dar por sentado que la gente conoce un tema técnico. Es algo que tiendo a olvidar y que necesito recordarme a mí mismo con regularidad. Si alguna vez sientes esa punzada de culpabilidad en el otro lado de la ecuación, siempre me resulta útil recurrir a este diagrama de Venn:

Venn Diagram crossing what you know vs. what others know in equal mass

Trabajar con JWTs constantemente, a diario, como parte de mi trabajo, desarrollando nuestro SDK PHP es uno de esos temas. Una vez que había mirado cómo usamos JWTs, eso era todo. Pero, con mi principio de "nunca asumir conocimiento" en su lugar, me doy cuenta de que hay mucha gente que no tienen ni idea de lo que son. Es más, algunos desarrolladores con cierta experiencia (incluso en la construcción y consumo de APIs) aún no las han utilizado o ni siquiera han oído hablar de ellas. El ritmo de evolución de las tecnologías API tiende a ser mucho más lento en las empresas más grandes o de mayor escala de lo que muchos creen. Estamos en 2023 en el momento de escribir este artículo y, sin embargo, muchos bancos y entidades farmacéuticas siguen utilizando SOAP.

Antes de sumergirnos en la anatomía de los JWTs, vale la pena señalar que este artículo incluye ejemplos con código. Si te apetece utilizar alguna de nuestras herramientas para crear JWTs, dirígete a este artículo de Benjamin Aronov que muestra cómo generar uno completamente dentro del panel de Vonage.

Conceptos básicos

JWT son las siglas de JSON Web Token. En un escenario de acrónimos un poco confuso, técnicamente significa JavaScript Object Notation Web Token en su forma completa. Hasta su introducción en un borrador fechado en julio de 2011, las formas más comunes de autenticación para las API web consistían en añadir una Clave API y un Secreto sin cifrar en la cadena de consulta de una solicitud o la Autenticación Básica, donde una de las Claves API o el Secreto (o ambos) se convierten en hash, normalmente con codificación base64 y se pasan como cabecera. Un JWT es un hash incluido en la cabecera de una solicitud (o podría estar en el cuerpo, pero eso es menos común), sustituyendo a los antiguos estilos de autenticación.

Autenticación existente: Los contras

Entonces, ¿por qué es necesaria una nueva técnica de autenticación?

Seguridad

Este tiene que ser el factor más significativo. Enviar una Clave API o Secreto sin cifrar en la cabecera (o en la cadena de consulta) para cada petición abre un vector de seguridad bastante grande. Hay más tráfico con las mismas credenciales abierto a ser olfateado, y tan pronto como esas claves son comprometidas, has abierto toda tu aplicación o cuenta.

Tiende a haber una trampa con respecto a la Autenticación Básica - el estilo en el que tomas {username}:{password} como una cadena y la codificas en base64. Muchos desarrolladores nuevos en la autenticación API pueden ver el hash resultante y pensar, "¡Eso parece seguro!" pero la realidad es que es fácilmente decodificado en sus dos partes secretas. Por ejemplo, visite https://emn178.github.io/online-tools/base64_decode.html y pegue c2VlLXRoYXQtd2FzOmVhc3k=.

La única capa real de seguridad que puedes crear al utilizar estos métodos es rotar tus claves. Dependiendo de su producto API, es posible que las grandes bases de código heredadas ni siquiera tengan la capacidad de rotar una combinación principal de clave/secreto (especialmente si están vinculadas directamente a una Account durante la creación de la cuenta).

Alcance

Anteriormente, con los tipos básicos de autenticación, se añadían nuevas claves a una cartera sobre las claves primarias, que normalmente se creaban con un conjunto de ámbitos. Esto puede resultar en una colección bastante extensa de claves utilizadas para varios productos o consultas específicas - rotar una gran cantidad de claves periódicamente puede volverse bastante engorroso.

Portabilidad

Al igual que con el ámbito, los secretos fijos de este tipo tienen los permisos de los usuarios, los ámbitos y el acceso a la API almacenados en el servidor. Esto hace que sean estáticos y no flexibles cuando se tiene una API más compleja con muchos parámetros a tener en cuenta al recibir una solicitud.

Anatomía de un JWT

Los JWT pretenden resolver estos tres problemas. Así es como están estructurados:

Información de cabecera

Cuando nos referimos a "cabecera", vale la pena señalar que se trata de la cabecera del JWT y no una cabecera de petición HTTP.

El servidor necesita información sobre cómo se ha creado el JWT. Como resultado de este requisito, la cabecera contendrá información sobre cómo se ha creado el JWT en dos claves:

  • alg que en muchos casos es probable que por defecto sea HS256

  • typ que identifica el token como un JWT (a medida que evolucione el estándar, es probable que haya iteraciones o nuevas versiones del tipo de token)

Carga útil

La carga útil de un JWT se presenta en forma de reclamacionesque son una serie de pares clave-valor que contienen información sobre el JWT. Los reservados más comunes (o *Registered Claim Names) son los siguientes:

  • issla fuente del JWT (aplicación, organización, etc.)

  • sub: un valor único para el emisor, al que se refieren las demás reclamaciones en el contexto del JWT

  • expfecha de caducidad del JWT

  • iat: cuando se creó el JWT (emitido en)

  • jtiun identificador único para este JWT

Los JWT son muy útiles para la autenticación porque puedes añadirles claims personalizados que sean relevantes para la aplicación que los consume. Tomemos, por ejemplo, el JWT de Vonage - cuando se utilizan nuestras APIs que soportan la autenticación JWT, se utiliza un claim personalizado, application_id personalizada. Vonage puede cotejar el JWT con la clave SSH privada de tu Account (que se habrá utilizado en el cliente de la solicitud para generar el JWT) y, si es válida, la solicitud puede enviarse rápidamente a la instancia de la aplicación correcta dentro de las API de Vonage.

Cómo hacer un JWT: Edición PHP

Como desarrollador PHP residente en mi equipo, voy a generar un JWT válido en el menor número de líneas de código posible para mostrar lo relativamente sencillo que es empezar. Esto es lo que necesitamos:

  • Un ID de aplicación del panel de control.

  • Se ha descargado una copia de la clave privada de la aplicación desde el panel de control.

Puede obtener ambos desde la configuración de la aplicación aquí:

Screenshot of Vonage Dashboard, accessing an Application's Settings

Usaremos el PHP JWT creator de Vonage en GitHub para esto. Para instalarlo, necesitarás composer.

composer require vonage/jwt

Y ahora, el código:

<?php

require_once "vendor/autoload.php";

$applicationId = "78d335fa-323d-0114-9c3d-d6f0d48968cf";
$privateKey = file_get_contents('private.key');
$generator = new Vonage\JWT\TokenGenerator($applicationId, $privateKey);
$jwt = $generator->generate();

¡Hecho!

Para utilizar esto en una solicitud, tendrá que añadirlo como Encabezado. Necesitaremos un Cliente HTTP para enviarlo. He elegido HTTPClient de Symfony para mostrar en qué pocas líneas podemos hacerlo. Para instalarlos, añádelos a tu proyecto con composer:

composer require symfony/http-client

Y luego vamos a POST una solicitud a la API de Messages de Vonage usando nuestro JWT:

use Symfony\Component\HttpClient\HttpClient;

$payload = [
	'message_type' => 'text',
	'text' => 'Using a JWT to send Vonage a request!',
	'to' => '44779999999',
	'from' => '44779499999',
	'channel' => 'sms'
]

$client = HttpClient::create();

$client->request('POST', 'https://api.nexmo.com/v1/messages/', [
	'headers' => [
		'Authorization' => 'Bearer ' . $jwt,
		'Content-Type' => 'application/json',
	],
	'json' => $payload
])

Y ahí lo tienes. Por supuesto, este es un ejemplo de cómo hacerlo. Si quieres hacer una integración completa, te recomiendo usar nuestro Core PHP SDK, que maneja muchos dolores de cabeza. Si PHP no es tu elección, ¡no pasa nada! También tenemos SDKs para Node, Java, Python, Ruby y NET.

Compartir:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondePromotor senior de desarrollo PHP

Actor de formación con una disertación sobre la comedia, llegué al desarrollo de PHP a través de la escena de las reuniones. Puedes encontrarme hablando y escribiendo sobre tecnología, o tocando/comprando discos raros de mi colección de vinilos.