OAuth 2.0 es fácil de usar y difícil de imaginar. Un botón de inicio de sesión desencadena redirecciones entre tres o cuatro partes, cada una con parámetros de nombres parecidos, y la mayoría de los errores vienen de una parte que se salta una comprobación que debía hacer. Un diagrama de secuencia es la forma más clara de ver quién envía qué a quién y en qué orden.
Este artículo dibuja el flujo que deberías usar hoy en casi cualquier cliente: el authorization code grant con PKCE. Recorre cada paso, explica qué comprueba cada parte y enumera los flujos antiguos que las recomendaciones actuales piden abandonar.
Las cuatro partes
| Rol en la especificación | En la práctica | Tiene |
|---|---|---|
| Propietario del recurso | El usuario | Sus credenciales |
| Cliente | Tu app web, single-page app o app móvil | Los tokens que recibe |
| Servidor de autorización | Tu proveedor de identidad | Cuentas de usuario, consentimientos, claves de firma |
| Servidor de recursos | Tu API | Los datos y las reglas sobre qué tokens acepta |
El cliente nunca ve la contraseña del usuario. Esa es la idea de OAuth: el servidor de autorización autentica al usuario y entrega al cliente un token con alcance y duración limitados.
Qué flujo usar en 2026
El marco original de OAuth 2.0, RFC 6749, definía varios grants. La OAuth 2.0 Security Best Current Practice, RFC 9700, publicada en enero de 2025, reduce las opciones:
- Authorization code con PKCE para el inicio de sesión de usuarios, desde cualquier tipo de cliente. Los clientes públicos (apps móviles, single-page apps) deben usar PKCE; para los clientes confidenciales con un secreto en el servidor se recomienda.
- No el implicit grant. Devuelve los tokens en la redirección del navegador, donde pueden filtrarse; los clientes no deberían usarlo.
- No el resource owner password credentials grant. Darle la contraseña del usuario al cliente anula el propósito; la BCP dice que no debe usarse.
- Client credentials para llamadas de servicio a servicio sin usuario de por medio.
El borrador de OAuth 2.1 reúne estas reglas en un solo documento, así que las bibliotecas nuevas las dan cada vez más por supuestas.
PKCE en un párrafo
Proof Key for Code Exchange, RFC 7636, protege el authorization code. Antes de redirigir, el cliente crea un code_verifier aleatorio (de 43 a 128 caracteres) y envía solo su hash SHA-256, el code_challenge, con code_challenge_method=S256. Cuando más tarde el cliente canjea el código por tokens, envía el verifier. El servidor lo hashea y compara. Un atacante que intercepte el código no puede usarlo sin el verifier, que nunca salió del cliente.
El flujo, paso a paso
- El usuario hace clic en Iniciar sesión. El cliente genera
state(un valor aleatorio ligado a la sesión del usuario) y el verifier y el challenge de PKCE. - El cliente redirige a
/authorizeconresponse_type=code,client_id, laredirect_uriregistrada, elscopesolicitado,statey el code challenge. - El servidor de autorización muestra su página de inicio de sesión y consentimiento. El cliente no participa; esto ocurre en el dominio del servidor.
- El usuario inicia sesión, completa la MFA si hace falta y consiente los scopes.
- El servidor redirige de vuelta a la
redirect_uriregistrada exacta con uncodede un solo uso y vida corta, y el mismostate. El cliente comprueba questatecoincide con lo que envió; si no, se detiene. El RFC 6749 recomienda una vida máxima del código de 10 minutos. - El cliente hace un POST a
/tokencon el código, la URI de redirección y elcode_verifier(más su autenticación de cliente, si es un cliente confidencial). Es una petición por el canal trasero, no una redirección. - El servidor devuelve los tokens: un access token, normalmente un refresh token y un ID token si usas OpenID Connect.
- El cliente llama a la API con
Authorization: Bearer <access token>. - La API valida el token y responde. Con access tokens JWT, comprueba en local la firma, el emisor, la audiencia, la caducidad y los scopes; con tokens opacos, pregunta al endpoint de introspección del servidor de autorización.
- Cuando el access token caduca, el cliente envía el refresh token por POST a
/token. - El servidor devuelve un access token nuevo, y en los clientes públicos un refresh token nuevo. El RFC 9700 exige que los refresh tokens de los clientes públicos estén ligados al emisor o se roten, para que un refresh token robado deje de funcionar tras un uso por cualquiera de las partes.
El diagrama de secuencia
Contenido del diagrama
- User
- Client app
- Authorization server
- API (resource server)
- access token expired
- 1. Sign in
- 2. GET /authorize + code_challenge, state
- 3. Login and consent page
- 4. Credentials, MFA, consent
- 5. Redirect to redirect_uri with code, state
- 6. POST /token: code + code_verifier
- 7. Access token, refresh token
- 8. GET /orders, Authorization: Bearer token
- 9. 200 OK
- 10. POST /token: refresh_token
- 11. New access token (and rotated refresh token)
Cómo leerlo:
- Cuatro líneas de vida, de izquierda a derecha: el usuario, la app cliente, el servidor de autorización y la API.
- Las flechas continuas con punta rellena son peticiones; las flechas discontinuas son respuestas y redirecciones de vuelta.
- Los pasos 2 a 5 son redirecciones por el canal delantero a través del navegador; el paso 6 es la petición del token por el canal trasero, donde PKCE marca la diferencia.
- El fragmento opt de abajo solo se ejecuta cuando el access token ha caducado.
- El bloque Markdown enumera las comprobaciones de cada parte, que es donde se esconden la mayoría de los errores reales.
Errores que aparecen en las revisiones
- No comprobar
state. Sin esa comprobación, un atacante puede completar un flujo de inicio de sesión en el navegador de la víctima con la cuenta del atacante. - Coincidencia laxa de la URI de redirección. El servidor debe comparar exactamente con la URI registrada; la coincidencia por prefijo o con comodines permite robar códigos.
- Tokens en el local storage de una single-page app. Cualquier inyección de scripts puede leerlos. Muchos equipos ponen un pequeño backend delante de la SPA (un backend-for-frontend) que guarda los tokens y da al navegador una cookie de sesión.
- APIs que aceptan cualquier token válido. Comprueba la audiencia o un token emitido para otra API funcionará en la tuya.
- Web views integradas en apps móviles. El RFC 8252 dice que las apps nativas deben usar el navegador del sistema, para que la app no pueda ver las credenciales del usuario.
- Access tokens de larga duración para evitar la lógica de refresco. Mantén cortos los access tokens y refréscalos; así una revocación surte efecto rápido.
Qué dibujar en un diagrama de OAuth
- Cada parte en su propia línea de vida, incluido el navegador si tu cliente tiene un backend.
- El canal delantero y el canal trasero diferenciados, porque tienen propiedades de seguridad distintas.
- Los nombres de los parámetros en las flechas:
state,code_challenge,code,code_verifier. Quienes revisan los buscan. - Quién valida qué. Las comprobaciones son el diseño; las flechas solo mueven datos.
Si dibujas el panorama de seguridad más amplio, el diagrama de arquitectura zero trust muestra dónde se sitúa el proveedor de identidad entre los demás controles, y el diagrama de arquitectura de un API gateway trata la validación de tokens una sola vez en el borde. El ejemplo de diagrama de secuencia explica con más detalle la notación usada aquí.
Constrúyelo en Archboard
- Inicia sesión con Google o GitHub y crea un diagrama.
- Del pack Secuencia, añade un Actor para el usuario y tres nodos Línea de vida para la app cliente, el servidor de autorización y la API, en una fila y con la misma altura.
- Dibuja cada mensaje como una arista recta entre líneas de vida, de arriba abajo, con los nombres de los parámetros en la etiqueta. Usa aristas discontinuas con punta abierta para las respuestas y las redirecciones.
- Añade un Fragmento combinado con el operador
optalrededor de los pasos de refresco. - Añade un bloque Markdown del pack Básico con las comprobaciones de cada parte.
El ejemplo usa 6 nodos de diagrama, dentro del plan Free.
Preguntas frecuentes
¿Qué diferencia hay entre OAuth 2.0 y OpenID Connect? OAuth 2.0 trata del acceso delegado: el cliente obtiene un token para llamar a una API. OpenID Connect añade identidad encima: un ID token que le dice al cliente quién es el usuario y un endpoint estándar de información del usuario.
¿Necesito PKCE si mi app tiene un client secret? El RFC 9700 lo recomienda también para los clientes confidenciales. Protege contra la inyección de códigos y cuesta un parámetro más en cada lado.
¿Se debe seguir usando el implicit grant? No. Las buenas prácticas actuales dicen que los clientes no deberían usarlo. Usa en su lugar el authorization code grant con PKCE, también en las single-page apps.
¿Dónde debe guardar los tokens una single-page app? Preferiblemente en ningún sitio del navegador: un backend-for-frontend puede guardar los tokens en el servidor y dar al navegador una cookie de sesión segura. Si los tokens tienen que vivir en el navegador, guárdalos en memoria, mantén cortos los access tokens y usa la rotación de refresh tokens.
¿Cómo valida la API un access token? Con access tokens JWT, comprobando la firma con las claves publicadas del servidor de autorización, además del emisor, la audiencia, la caducidad y el scope. Con tokens opacos, llamando al endpoint de introspección.