OAuth es autorización, OIDC es autenticación
OAuth 2.0 responde a una sola pregunta: ¿puede esta aplicación actuar en nombre de este usuario? Para ello, emite access tokens para APIs. Deliberadamente, no dice nada sobre quién es el usuario. Ese vacío causó años de confusión, y OpenID Connect es la solución.
OpenID Connect es una pequeña capa de identidad sobre OAuth 2.0. Estandariza el flujo de inicio de sesión, define un ID token que certifica la identidad y publica metadatos para que los clientes puedan configurarse sin adivinanzas. Cuando haces clic en “Iniciar sesión con Google” o en un botón de SSO empresarial, estás utilizando OIDC.
La regla práctica: si necesitas saber quién es el usuario, usa OIDC. Si necesitas que una aplicación haga algo en su nombre, usa OAuth. La mayoría de los inicios de sesión requieren ambos, razón por la cual generalmente se implementan juntos.
El ID token
La pieza central de OIDC es el ID token: un JWT firmado por el proveedor de identidad. Este contiene los claims que tu aplicación necesita para establecer una sesión.
sub— el identificador único y estable del usuario.iss— el issuer, para que sepas qué proveedor lo firmó.aud— el client id para el cual fue emitido; un token destinado a otra aplicación debe ser rechazado.expyiat— cuándo expira y cuándo fue emitido.nonce— refleja el valor que enviaste, para vincular el token a este intento de inicio de sesión.email,name,picture— claims de perfil, siempre que los scopes solicitados lo permitan.
El ID token es para tu client. No es la credencial que envías a las APIs downstream; esa es la función del access token. Mantener ambos conceptos separados evita un error de diseño muy común.
Discovery
Cada proveedor compatible publica un documento de discovery:
https://accounts.example.com/.well-known/openid-configuration
Este documento enumera los endpoints de autorización, token, userinfo y JWKS, además de los scopes y algoritmos soportados. Los clientes lo obtienen al iniciar y se configuran automáticamente, evitando así el hard-coding y permitiendo que los cambios del proveedor se apliquen de forma automática.
El flujo de código de autorización con PKCE
El flujo recomendado evita que las credenciales lleguen al navegador. El navegador solo maneja un código de corta duración.
- El cliente genera un
code_verifieraleatorio, lo transforma mediante un hash en uncode_challengey redirige el navegador al proveedor conscope=openid. - El usuario se autentica en el proveedor; este es el único lugar donde se introduce una contraseña o un segundo factor.
- El proveedor redirige de vuelta con un
codede autorización. - El backend intercambia el código, junto con el verificador, por un ID token y un access token.
- El cliente valida el ID token y crea una sesión.
PKCE (Proof Key for Code Exchange) vincula el código al cliente que lo solicitó. Un código interceptado durante el tránsito es inútil sin el verificador. Envía siempre state para prevenir CSRF y nonce para vincular el ID token a la solicitud.
Scopes y claims
Los scopes deciden qué claims puedes recibir.
openid— obligatorio; sin él, la solicitud es OAuth simple, no OIDC.profile— nombre, foto y otros campos del perfil.email— el email del usuario y si está verificado.offline_access— solicita un refresh token para que la aplicación pueda actuar posteriormente.
Solicita solo lo mínimo necesario. Cada scope adicional implica más datos que proteger y, en algunos proveedores, genera más fricción en el consentimiento para el usuario.
El endpoint userinfo
El ID token a menudo contiene solo la información básica. Para obtener más datos del perfil, llama al endpoint userinfo utilizando el access token:
const userinfo = await client.userinfo(tokenSet.access_token);
// { sub, name, email, email_verified, picture, ... }
Trata el sub de userinfo como la fuente autorizada y asegúrate de que coincida con el sub del ID token. Nunca confíes en un email como un identificador estable, ya que los usuarios pueden cambiarlos.
Validando el ID token
La validación es el paso que hace que todo el proceso sea seguro, y es el paso que más a menudo se hace mal. Decodificar el payload no es lo mismo que verificarlo; cualquier persona puede crear un token con cualquier claim.
Antes de confiar en un claim:
- Signature — verifícalo con la clave pública del proveedor desde el endpoint JWKS, utilizando un algoritmo permitido.
- Issuer —
issdebe ser igual al proveedor esperado. - Audience —
auddebe ser tu client id. - Expiry —
expdebe ser una fecha futura, considerando un pequeño margen de error del reloj (clock skew). - Nonce — debe coincidir con el valor que enviaste para este login.
Utiliza una librería mantenida como openid-client y deja que ella se encargue de estos cinco puntos. No intentes implementar el parsing de JWT a mano para la autenticación.
Sesiones después del login
OIDC autentica una sola vez, al iniciar sesión. No gestiona la sesión de tu aplicación. Después de validar el ID token, crea tu propia sesión —ya sea una cookie o un token— basada en sub.
Ten claras estas tres cosas:
- El ID token es para tu cliente y sirve para probar la identidad.
- El access token es para realizar llamadas a APIs.
- Tu sesión es la forma en que tu app recuerda al usuario a través de las solicitudes.
Mezclarlos provoca que los tokens del proveedor se filtren al navegador o que se utilice un ID token como credencial de API; ambos son errores.
Cerrar sesión
El cierre de sesión local es lo primero: limpia tu sesión para que el usuario quede desconectado de tu aplicación. Esto siempre está bajo tu control y es totalmente fiable.
El cierre de sesión federado es un proceso de “mejor esfuerzo” (best-effort). Puedes redirigir al endpoint de finalización de sesión del proveedor con un id_token_hint, pero no todos los proveedores lo respetan y es posible que la redirección no se complete. Diseña tu flujo de modo que limpiar tu propia sesión sea suficiente, y nunca dependas del proveedor para cerrar la sesión del usuario.
Cuándo usar OIDC
OIDC es la opción adecuada cuando:
- Quieres evitar almacenar contraseñas por completo.
- Necesitas SSO empresarial o botones de “Iniciar sesión con…”.
- Tu aplicación es una de varias que deben compartir un mismo inicio de sesión.
- Quieres que un especialista gestione el MFA y la recuperación de cuentas.
Es más complejo que un simple formulario de contraseña. Para una herramienta interna pequeña con unos pocos usuarios, Session Auth y Password Hashing pueden ser más sencillos y totalmente suficientes.
Mejores prácticas
- Utiliza siempre el flujo de código de autorización con PKCE.
- Envía y verifica tanto
statecomononce. - Valida el ID token por completo: firma, emisor, audiencia y expiración.
- Utiliza discovery en lugar de endpoints hard-coded.
- Solicita los scopes mínimos necesarios.
- Mantén tu sesión separada de los tokens del proveedor.
- Almacena los client secrets en el backend, nunca en el navegador.
Errores comunes
- Tratar OAuth como autenticación y leer la identidad desde un access token.
- Decodificar el ID token sin verificar su firma.
- Omitir las comprobaciones de
audoiss, permitiendo que se acepte un token de otra aplicación. - Utilizar el implicit flow y exponer los tokens en la URL.
- Confiar en la dirección de correo electrónico como la primary key del usuario.
- Enviar tokens del proveedor a tus propias APIs como si fueran credenciales de sesión.
- Olvidar que el logout debe cerrar primero tu sesión.
Próximos pasos
Si aún no lo has leído, comienza con OAuth 2.0 para entender el protocolo de autorización que extiende OIDC, y la guía de JWT para conocer el formato de los tokens. Una vez que el login sea exitoso, la guía de Session Auth muestra cómo mantener al usuario autenticado, y RBAC & Permissions cubre qué acciones tienen permitido realizar.