La guía

¿Qué flujo debo elegir?

Un «flujo» (o «grant») es la manera en que una aplicación obtiene sus tokens. Hay varios porque las aplicaciones son muy distintas: un sitio web, una aplicación móvil, una tele, un servicio sin usuario… no tienen las mismas restricciones ni los mismos secretos que proteger.

Vea también: los flujos como diagramas de secuencia · funciones avanzadas explicadas (PAR, JAR, JARM, DPoP, CIBA) · la línea de tiempo de OAuth y OpenID Connect

En dos preguntas

  1. ¿Hay una persona iniciando sesión? No, es un servicio que habla con otro servicio → Client Credentials.
  2. Sí. ¿Dónde se ejecuta la aplicación?
    • Sitio web, aplicación móvil, aplicación de una sola página (SPA), aplicación de escritorio, con navegador → Authorization Code + PKCE. Esa es la respuesta en el # % de los casos.
    • Dispositivo sin navegador ni teclado (TV, consola, objeto conectado, herramienta de línea de comandos) → Device Code.

Todo lo demás existe por razones históricas o necesidades específicas. Refresh Token no es un flujo de inicio de sesión: es un complemento para mantener viva la sesión.

¿Por qué tantos flujos?

OAuth 2.0 (2012) tenía que servir tanto a servidores capaces de guardar un secreto como a aplicaciones de navegador que no pueden. De ahí implicit para las SPA, password para las aplicaciones «de confianza» y code para los servidores. Con los años quedó claro que los tokens en la URL se filtraban (implicit) y que entregar la contraseña a la aplicación anulaba todo el sentido (password). OAuth 2.1 y las recomendaciones de seguridad actuales han devuelto todo a code + PKCE, conservando client credentials y device para sus casos propios. OIDC añadió el flujo hybrid para obtener la identidad de inmediato.

Los flujos, uno por uno

Authorization Code + PKCEEl flujo estándar para cualquier persona que inicia sesión.Recomendado

Úselo cuando: una persona inicia sesión en un sitio web (con o sin servidor), una SPA, una aplicación móvil o de escritorio. Con un servidor capaz de guardar un secreto, añada el client_secret; sin él (SPA, móvil), basta PKCE.

Por qué existe: el navegador solo recibe un código de un solo uso y corta duración; los tokens van directamente del servidor de la aplicación al OP («back channel»). PKCE vincula el código a quien lo pidió, de modo que un código interceptado no sirve a nadie más.

Trampas: olvidar PKCE (ahora obligatorio incluso para clientes confidenciales), no comprobar state y nonce, aceptar redirect_uri demasiado amplios, tokens en localStorage en una SPA.

Guía paso a paso:

  1. La aplicación genera code_verifier (un secreto aleatorio), state, nonce, y calcula code_challenge = SHA-256(code_verifier).
  2. Envía a la persona a /authorize?response_type=code&code_challenge=…&state=…&nonce=….
  3. El OP autentica a la persona y la devuelve a redirect_uri?code=…&state=….
  4. La aplicación llama a /token con el código y el code_verifier (y su secreto si lo tiene).
  5. Recibe el ID token, el access token (y el refresh token) y comprueba después la firma, iss, aud y nonce.
Hybrid (code id_token, code token…)Código más ID token directamente en la redirección.Casos específicos

Úselo cuando: la aplicación necesita la identidad de inmediato (antes del intercambio del código), por ejemplo para validar la sesión en el servidor o porque una biblioteca antigua (ASP.NET, Java EE) lo configura por defecto.

Por qué existe: OIDC quería permitir leer la identidad de inmediato sin renunciar al código para obtener los tokens de forma segura. El c_hash y el at_hash del ID token vinculan el código y el access token con esa identidad.

Trampas: tokens en el fragmento de la URL (visibles para el historial y los scripts), c_hash/at_hash sin comprobar y un nonce obligatorio olvidado. Prefiera el flujo de código simple salvo que algo se lo impida.

Guía paso a paso:

  1. /authorize?response_type=code id_token&nonce=… (o code token, code id_token token).
  2. El OP devuelve #code=…&id_token=…&state=… en el fragmento (response_mode=fragment por defecto) o por POST (form_post).
  3. La aplicación comprueba el ID token y su c_hash.
  4. Intercambia el código por los demás tokens, como en el flujo de código.
Implicit (id_token, id_token token)Los tokens llegan directamente en la URL.Desaconsejado

Úselo cuando: casi nunca en trabajos nuevos. Se encuentra en SPA antiguas, o para comprobar que una aplicación realmente lo prohíbe.

Por qué existe: antes de que los navegadores gestionaran las llamadas entre orígenes (CORS) y PKCE, una SPA no podía llamar a /token, así que se le entregaban los tokens directamente.

Trampas: el token viaja en la URL: historial, registros de proxy, cabecera Referer, extensiones. Sin refresh token, sin vinculación con quien llama. Eliminado de OAuth 2.1.

Guía paso a paso:

  1. /authorize?response_type=id_token token&nonce=….
  2. El OP devuelve #id_token=…&access_token=…&state=….
  3. Un script de la página lee el fragmento y verifica el token.
Client CredentialsSin persona: el servicio se autentica por sí mismo.Máquina a máquina

Úselo cuando: un servicio, una tarea programada o un demonio llama a una API en su propio nombre: sincronización, tarea nocturna, microservicios que hablan entre sí.

Por qué existe: muchas llamadas a API no tienen ninguna persona detrás. El cliente demuestra su identidad (secreto o, mejor, una aserción firmada) y recibe un access token limitado a sus scopes.

Trampas: sin ID token ni refresh token (es normal). No ponga nunca este secreto en una aplicación distribuida (móvil, SPA). Conceda el mínimo de scopes y rote el secreto.

Guía paso a paso:

  1. POST /token con grant_type=client_credentials, scope=… y la autenticación del cliente (secreto Basic o en el cuerpo).
  2. El OP responde con un access token.
  3. El servicio lo envía a la API: Authorization: Bearer ….
Refresh TokenRenueve un access token sin volver a preguntar a la persona.Complemento

Úselo cuando: quiere access tokens de corta duración (unos minutos) manteniendo a la persona conectada mucho tiempo. Se solicita con el scope offline_access.

Por qué existe: cuanto más vive un token, peor es su robo. El refresh token se queda en el lado de la aplicación, lejos de las API, y solo sirve para renovar.

Trampas: un refresh token robado significa acceso prolongado: almacenamiento seguro, rotación (uno nuevo en cada uso, el anterior queda invalidado) y detección de reutilización.

Guía paso a paso:

  1. POST /token con grant_type=refresh_token&refresh_token=….
  2. El OP devuelve un nuevo access token (y a menudo un nuevo refresh token, quedando revocado el anterior).
Device Code (RFC 8628)Inicie sesión en otro dispositivo.Dispositivos sin navegador

Úselo cuando: televisor, consola, objeto conectado, impresora, herramienta de línea de comandos: el dispositivo no tiene navegador ni teclado cómodo.

Por qué existe: escribir una contraseña con un mando a distancia es penoso y arriesgado. Se muestra un código corto; la persona lo introduce en su teléfono u ordenador, donde se autentica con normalidad.

Trampas: código de corta duración y de un solo uso, sin consultar demasiado rápido (slow_down) y con límites de intentos para que un código no pueda adivinarse. El phishing es posible: muestre claramente lo que la persona está autorizando.

Guía paso a paso:

  1. El dispositivo llama a /device_authorization y recibe device_code, user_code y la dirección de verificación.
  2. Muestra «vaya a … e introduzca ABCD-EFGH».
  3. La persona se autentica e introduce el código en su teléfono.
  4. Mientras tanto, el dispositivo consulta /token con el device_code. Primero authorization_pending y luego los tokens.
Resource Owner Password CredentialsLa aplicación recibe la contraseña directamente.Desaconsejado

Úselo cuando: conviene evitarlo. A veces se tolera para una migración desde un sistema antiguo o pruebas automatizadas en un entorno controlado.

Por qué existe: una transición para aplicaciones que ya recogían contraseñas, sin cambiar su interfaz.

Trampas: la aplicación ve la contraseña: exactamente lo que OIDC intenta evitar. Sin autenticación multifactor, sin SSO, phishing más fácil. Eliminado de OAuth 2.1.

Guía paso a paso:

  1. POST /token con grant_type=password&username=…&password=….
  2. El OP responde con los tokens, o rechaza si se exige un segundo factor.

También en la práctica

  • private_key_jwt y JWT Bearer (RFC 7523): un servicio prueba su identidad con una aserción firmada en lugar de un secreto compartido. Ideal para intercambios entre sistemas. En ID-Kit del lado del proveedor de pruebas; todavía no del lado de la aplicación de pruebas.
  • Token Exchange (RFC 8693): intercambiar un token por otro, para una API que llama a otra API en nombre de la persona. En ID-Kit.
  • PAR y JAR (RFC 9126 y 9101): la solicitud de autorización se envía de servidor a servidor, o se firma. En ID-Kit: proveedor de pruebas (PAR y JAR) y aplicación de pruebas (PAR).
  • CIBA : la autenticación se realiza por otro canal, iniciada por el servidor (centro de llamadas, banco). En ID-Kit (proveedor de pruebas, modo poll).

Todos los detalles en imágenes: diagramas de secuencia.

Las protecciones que lo acompañan

  • PKCE: demuestra que quien intercambia el código es quien lo pidió.
  • state: vincula la respuesta con la solicitud, contra CSRF.
  • nonce: vincula el ID token con la sesión de la aplicación, contra la reproducción.
  • redirect_uri exacto: el OP solo envía el código a una dirección registrada, carácter por carácter.

Pruebe cada flujo. El proveedor de pruebas de ID-Kit puede hacer todos estos flujos, con errores simulados; la aplicación de pruebas los ejecuta contra su proveedor real.