Seguridad: OAuth y JWT
Cómo se protege una API que no guarda sesión: TLS para el canal, HTTP Basic, OAuth 2.0 para delegar la autorización, y JWT con su estructura y sus claims.
El panorama: qué protege cada pieza
REST no trae seguridad propia: no forma parte del estilo. Lo que se hace es combinar mecanismos que ya existen en HTTP y alrededor de HTTP, y lo primero es tener claro qué resuelve cada uno, porque el examen mezcla las columnas.
| Mecanismo | Qué aporta |
|---|---|
| TLS | Confidencialidad e integridad del canal, y autenticación del servidor |
| HTTP Basic | Autenticación del cliente enviando usuario y contraseña codificados |
| OAuth 2.0 | Autorización delegada: dar acceso a un tercero sin entregarle la contraseña |
| JWT | Formato de testigo que transporta de forma verificable la identidad y los permisos |
HTTP Basic merece un aviso: las credenciales van codificadas en base64, que no es cifrado sino una simple representación en texto. Cualquiera que vea el tráfico las lee, así que Basic sin TLS por debajo equivale a enviar la contraseña en claro.
Los mecanismos se acumulan, no se eligen: TLS protege el canal y por dentro viaja el testigo que identifica y autoriza. Uno no sustituye al otro.
Para el examen
Qué protege TLS: el canal: confidencialidad, integridad y autenticación del servidor
Qué viaja por dentro: el testigo que identifica y autoriza
HTTP Basic sin TLS: no vale: base64 no es cifrado
OAuth 2.0 y el esquema Bearer
OAuth 2.0 resuelve un problema concreto: que una aplicación pueda acceder a los recursos de un usuario en otro servicio sin conocer su contraseña. El usuario se autentica ante el proveedor, este emite un testigo de acceso limitado en alcance y en tiempo, y la aplicación presenta ese testigo en cada llamada.
Conviene decirlo con precisión porque es la trampa habitual: OAuth 2.0 es un marco de autorización delegada, no un protocolo de autenticación. Quien añade la autenticación de usuarios sobre él es OpenID Connect, que es una capa construida encima.
El testigo se envía en la cabecera Authorization con el esquema Bearer, que significa literalmente «al portador»: quien lo lleva, lo usa. De ahí que un testigo Bearer robado sirva a quien lo roba, y de ahí que TLS no sea opcional.
GET /api/alumnos/482/falladas HTTP/1.1
Host: api.llegandoalcorte.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0ODIi...
Accept: application/jsonOAuth 2.0 autoriza, no autentica. Si una pregunta define OAuth como «autenticación basada en token», está describiendo el uso corriente, no el estándar.
Para el examen
Qué hace: AUTORIZA, no autentica
Qué permite: que una aplicación acceda a recursos del usuario sin conocer su contraseña
Cómo: con un testigo de alcance y duración limitados
Esquema de presentación: Bearer
JWT: estructura y firma
JWT (JSON Web Token) es un formato de testigo compacto, pensado para viajar en una cabecera HTTP. Tiene tres partes separadas por puntos: cabecera, carga y firma. Cada una es un objeto JSON codificado en base64, salvo la firma, que es el resultado del cálculo criptográfico.
cabecera . carga . firma
cabecera { "alg": "HS256", "typ": "JWT" }
carga { "sub": "482",
"iat": 1786000000,
"exp": 1786003600,
"plan": "largo" }
firma HMAC-SHA256(
base64url(cabecera) + "." + base64url(carga),
clave secreta que solo conoce el servidor )La cabecera declara el algoritmo con el que se ha firmado. El servidor calcula la firma sobre la cabecera y la carga usando una clave que solo él conoce, y al recibir el testigo repite el cálculo: si coincide, el contenido no se ha tocado. Así puede confiar en el testigo sin haber guardado nada, que es justo lo que necesita un servicio sin estado.
La carga está codificada, no cifrada: cualquiera puede leerla. La firma impide modificarla, no impide verla, así que en un JWT no se meten datos sensibles.
Para el examen
Sus tres partes: cabecera, carga y firma, separadas por puntos
Cómo va la carga: codificada en base64, NO cifrada
Consecuencia: cualquiera puede leerla: no se meten datos sensibles
Los claims y la ausencia de sesión
Los datos que van en la carga de un JWT se llaman claims: afirmaciones sobre el sujeto del testigo. Unos están registrados y significan lo mismo en todas partes, y otros los define la aplicación para sus propias necesidades, como el plan contratado o el papel del usuario.
| Claim | Significado |
|---|---|
| sub | Sujeto: a quién se refiere el testigo |
| iat | Momento en que se emitió |
| exp | Momento a partir del cual deja de aceptarse |
Como el servicio no guarda sesión, el cliente tiene que enviar el testigo en todas y cada una de las peticiones: no hay nada al otro lado que recuerde que ya se identificó hace un minuto. Esa es la consecuencia práctica más visible de que REST sea sin estado, y también su punto débil, porque un testigo emitido no se puede retirar antes de que expire salvo que se monte una lista de revocación, que es precisamente volver a guardar estado.
Para el examen
Qué son los claims: las afirmaciones de la carga
sub, iat y exp: sujeto, fecha de emisión y caducidad
Su punto débil: no se puede revocar antes de expirar
El remedio y su precio: una lista de revocación, que es volver a guardar estado