Sesenta peticiones por hora contra cinco mil, el token que cualquiera puede leer, y el secreto que sobrevive a una redirección.
⏱ 16 min de lectura
Identificarse ante una API no es solo poder entrar en lo privado. En GitHub, el límite pasa de sesenta peticiones por hora a cinco mil:
Salida en pantalla
sin identificarse: 60 peticiones/hora
identificado: 5000 peticiones/hora (83 veces más)
Así que la primera razón para autenticarse suele ser poder trabajar, y no el acceso a nada secreto.
El problema es que hay cuatro sitios donde meter una credencial, media docena de esquemas con nombres parecidos, y un montón de formas de que el secreto acabe en un sitio donde no debería.
El cuarto está mal, y esa es la primera regla de la lección. Una credencial en la dirección acaba en los registros del servidor, en los del repartidor de carga, en el historial del navegador y en la cabecera Referer que se manda al pinchar un enlace. Todos esos sitios se guardan durante años y los lee gente que no debería.
Algunas APIs solo ofrecen esa forma, y entonces no hay opción. Cuando ofrecen las dos, siempre la cabecera.
Eso no está cifrado. Es base64, que es una codificación reversible por cualquiera. El usuario y la contraseña viajan a efectos prácticos en claro, y lo único que los protege es que la conexión sea HTTPS.
Sigue siendo aceptable en dos casos: sobre HTTPS y con una contraseña que sea un token generado, no la de la persona. Muchas APIs la usan así, poniendo el token de usuario y dejando la contraseña vacía.
Eso implica que un token robado es acceso completo hasta que caduque o lo revoquen, y de ahí salen las tres reglas prácticas: que caduquen, que se puedan revocar, y que nunca estén en el código.
Hay dos familias de tokens y se confunden constantemente.
Tokens opacos. Una cadena aleatoria que no significa nada. El servidor la busca en su base de datos y mira a quién pertenece. Ventaja: se revocan borrando una fila, al instante. Inconveniente: una consulta por petición.
Tokens con contenido, los JWT. Traen la información dentro y van firmados, así que el servidor los valida sin consultar nada.
Esto genera más confusión que ninguna otra cosa del tema, así que vamos a abrir uno:
Salida en pantalla
trozos: 3
cabecera {'alg': 'HS256', 'typ': 'JWT'}
carga {'sub': '123', 'nombre': 'Ana', 'exp': 1790100000, 'rol': 'admin'}
firma (lo único que lo protege)
Tres trozos separados por puntos, y los dos primeros son base64 que cualquiera descodifica. Ahí están el usuario, el nombre y el rol, legibles con tres líneas de Python y sin ninguna clave.
De ahí salen las dos consecuencias que hay que tener claras:
Un JWT no está cifrado, está firmado. La firma impide modificarlo, no leerlo. Nunca metas dentro nada que no quieras que se vea: ni contraseñas, ni datos personales de más, ni identificadores internos que revelen cosas.
Un JWT no se puede revocar. Es su gran inconveniente y el que la gente descubre tarde. Como el servidor lo valida solo con la firma, no consulta nada, y por tanto no hay nada que borrar. Si alguien roba un token con dos horas de vida, tiene dos horas de acceso y no puedes hacer nada.
Por eso el esquema habitual son dos tokens:
Vida
Para qué
De acceso
minutos
Va en cada petición
De refresco
días o semanas
Solo sirve para pedir uno de acceso nuevo
El de acceso caduca enseguida, así que robarlo sirve de poco. El de refresco dura, y como solo se usa contra un punto concreto y sí se guarda en la base de datos, se puede revocar.
El exp de arriba, 1790100000, es la fecha de caducidad en segundos desde 1970:
Salida en pantalla
1790100000 = 2026-09-22 18:00:00+00:00
Comprobarla antes de mandar la petición, en lugar de esperar el 401, ahorra una ida y vuelta:
python
import time
deftoken_valido(carga, margen=60):return carga['exp']- margen > time.time()
El margen es importante: si el token caduca dentro de dos segundos, la petición llegará caducada.
OAuth asusta por el diagrama, y la idea es sencilla: dar permiso a un programa sin darle tu contraseña.
Cuando una aplicación te pide entrar con Google y te lleva a una página de Google donde dice "esta aplicación quiere ver tu correo, ¿aceptas?", eso es OAuth. Tu contraseña se la das a Google, no a la aplicación, y la aplicación recibe un token limitado a lo que aceptaste.
Hay dos casos y es importante distinguirlos, porque casi todo lo que asusta es del segundo:
Cuando el token es tuyo y ya está. Entras en la web de la API, generas un token personal, lo copias. No hay flujo ni diagrama: