¿Qué es OpenID Connect (OIDC) y cómo implementarlo bien desde el día uno?

Autor: Jeffry Chaves, Ing. en Sistemas – Diccionario Informático

Cuando alguien me pregunta qué es OpenID Connect, lo resumo así: OIDC es una capa de autenticación construida sobre OAuth 2.0. OAuth resuelve permisos (“¿puede esta app acceder a X?”); OIDC resuelve identidad (“¿quién eres?”) y lo hace emitiendo un ID Token (normalmente un JWT) con claims verificables sobre el usuario. Con esto obtienes inicio de sesión (SSO), confianza entre Relying Parties (RP) y OpenID Providers (OP) y un camino ordenado para pedir datos de perfil vía scopes y el endpoint UserInfo.
Si lo implementas bien, te llevas: login consistente entre plataformas (web, móvil, backend), menor fricción para usuarios, y un marco estándar para seguridad (PKCE, nonce, state, validación de firma, rotación de keys JWKS, etc.).


1) OIDC en 5 minutos: definición, componentes y relación con OAuth 2.0

  • Componentes:

    • OP (OpenID Provider): el “servidor de identidad” que autentica y firma tokens.

    • RP (Relying Party) o Client: tu app que confía en lo que el OP afirma.

    • Usuario: quien se autentica.

  • Tokens:

    • ID Token (JWT): prueba de autenticación con claims como iss, aud, sub, exp, y opcionalmente email, name, etc.

    • Access Token: para acceder a APIs (autorización), no para identificar.

  • Scopes y claims:

    • openid (obligatorio) activa OIDC. Otros: profile, email, phone, address.

    • “Claims” son atributos (p. ej., email_verified) que llegan en el ID Token o vía /userinfo.

  • Relación con OAuth 2.0:

    • OAuth 2.0 define cómo obtener tokens; OIDC define qué datos de identidad se devuelven y cómo validarlos.

    • Moral de la historia: no uses Access Token como identidad; la identidad viene del ID Token + validación.


2) Cómo funciona OIDC paso a paso (del login al UserInfo)

  1. El usuario pulsa “Iniciar sesión” en el RP.

  2. Redirijo al Authorization Endpoint del OP con response_type, client_id, redirect_uri, scope=openid ..., state y (si corresponde) PKCE (code_challenge, code_challenge_method).

  3. El OP autentica (password, MFA, passkeys, lo que tengas).

  4. El OP devuelve al redirect_uri con code (y state para CSRF).

  5. Intercambio ese code en el Token Endpoint (envío code_verifier si usé PKCE).

  6. Recibo ID Token (JWT) y normalmente Access Token.

  7. Valido el ID Token: firma (JWK del OP), iss, aud, exp, iat, nonce (si apliqué).

  8. (Opcional) Llamo a /userinfo con el Access Token para claims adicionales.

Tips rápidos que nunca me han fallado:

  • Siempre PKCE para SPAs/nativas; y aun con backend, no estorba.

  • Siempre nonce y state; son tus cinturones de seguridad.

  • Clock skew: tolera unos segundos/minutos al validar exp/iat para evitar falsos negativos por desajuste horario.


3) Flujos OIDC según tu tipo de aplicación (SPA, móvil, backend, híbrido)

  • SPA (Single-Page App): Código + PKCE (nada de implícito). ID Token y Access Token deben guardarse de forma segura (ideal: en memoria; evita localStorage cuando puedas, considera token rotation y HttpOnly cookies si el backend colabora).

  • Móvil/Nativas: Código + PKCE con AppAuth o SDK del proveedor. Usa custom URI schemes o Android App Links/Universal Links.

  • Backend (server-rendered): Código (PKCE opcional). Tokens del lado servidor, sesiones seguras, y protección CSRF.

  • Híbridas (BFF / Backend-for-Frontend): la app web habla con su backend; el backend guarda tokens y emite cookie de sesión HttpOnly al browser. Reduce superficie de ataque en el cliente.

Regla práctica: si el navegador está expuesto, PKCE. Si manejas tokens en el cliente, reduce su vida útil y considera rotación.


4) ID Token vs Access Token: qué valida cada uno y errores frecuentes

  • ID Token: prueba de que el OP autenticó al usuario. Lo verifico con la JWKS del OP (algoritmo RS256/ES256 común), checo iss (emisor), aud (tu client_id), exp/iat (vigencia), nonce (mitigar replay), y que no esté revocado.

  • Access Token: su audiencia suele ser la API (no tu client_id). No lo uses para mostrar el nombre del usuario; para eso está el ID Token o /userinfo.

  • Errores típicos:

    • Tratar el Access Token como identidad.

    • No validar firma/iss/aud.

    • No usar nonce en flujos front-channel.

    • Olvidar kid rotation: cuando cambia la key en JWKS, tu verificador debe poder refrescarla.


5) Scopes y claims: qué pedir, por qué y cómo equilibrar privacidad y UX

  • Pide sólo lo que necesites: openid + email si envías notificaciones; profile si rellenas nombre/imagen.

  • Principio de mínima exposición: menos scopes = menos fricción.

  • UX: explica por qué pides email o phone; sube conversiones si el usuario ve valor.

  • Recomendado: documenta qué claims usas realmente y dónde (perfil, facturación, soporte).


6) OIDC vs SAML vs OAuth 2.0: cuándo elegir cada uno

  • OIDC: moderno, JSON/REST, perfecto para web/móvil/APIs; soporte nativo en SDKs actuales.

  • SAML: XML, fuerte en ecosistemas enterprise y apps legadas (B2E), excelente para SSO con IdPs corporativos clásicos.

  • OAuth 2.0 “puro”: autorización a recursos; si necesitas identidad verificable, añade OIDC.
    Mi criterio: si tu target son apps modernas y móviles, ve con OIDC; si integras SaaS legacy o portales enterprise, puede que SAML siga siendo el camino.


7) Seguridad práctica en OIDC: PKCE, nonce/state, JWKS, iss/aud/exp

Checklist de mínimos que aplico en proyectos:

  • PKCE: S256 siempre que puedas.

  • state anti-CSRF y nonce anti-replay.

  • Validación del ID Token completa (firma y claims).

  • Rotación de keys: tu cliente debe refrescar JWKS automáticamente y cachear con expiración.

  • Límites de tiempo: tokens cortos + refresh tokens con rotación (si tu OP lo permite).

  • TLS estricto y redirect URIs exactas (evita comodines).

  • Logs y trazabilidad: registra iss, sub, client_id, y eventos de revocación.


8) Descubrimiento y endpoints clave (/.well-known, auth, token, userinfo)

El Discovery de OIDC (documento JSON /.well-known/openid-configuration) publica:

  • issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, jwks_uri, end_session_endpoint (si está soportado), scopes_supported, response_types_supported, claims_supported, etc.
    Con ese JSON tu cliente autoconfigura endpoints, conoce algoritmos soportados y ubica la JWKS para validar firmas. Asegúrate de cachear este documento con una política razonable y reintentos.


9) Logout en OIDC: opciones y consideraciones reales

  • RP-initiated logout: tu app inicia el cierre de sesión llamando al end_session_endpoint con el ID Token como id_token_hint.

  • Front-channel: navega el browser para “avisar” a sesiones; simple pero dependiente del navegador.

  • Back-channel: notificación server-to-server; más fiable, requiere endpoints del lado RP.

  • Single Logout no es automático: alinea tiempos de sesión entre RP y OP y define qué pasa con cookies/sesiones locales.


10) Checklist de implementación + recursos para ir a producción

Antes de producción:

  • Registro de client: redirect_uris exactas; si hay móvil, añade app links/URI schemes.

  • Flujo correcto según tipo de app (Código + PKCE en SPAs/nativas).

  • Validación completa del ID Token (firma y claims).

  • PKCE + state + nonce funcionando y testeado.

  • Rotación JWKS y manejo de kid implementados.

  • Tokens de vida corta + refresh con rotación (si aplica).

  • Logs/alertas para expiración, invalidación y anomalías.

  • Política de scopes/claims documentada.

  • Discovery cacheado y con backoff de reintento.

  • Estrategia de logout definida (front/back channel, RP-initiated).


Conclusión

OIDC te da una vía estándar, segura y flexible para saber quién es el usuario y compartir esa verdad entre aplicaciones. Si combinas flujo adecuado, validación estricta y una buena higiene de scopes/claims, tendrás SSO sólido, menos incidencias y una base extensible para MFA, passkeys o federaciones con otros IdPs. Cuando me toca priorizar, empiezo por Código + PKCE, validación del ID Token y disciplina en el Discovery/JWKS. Lo demás fluye.


FAQs

¿Puedo usar OIDC sólo con SPAs?
Sí, pero usa Código + PKCE y evita exponer secretos en el cliente. Considera BFF si quieres reducir superficie.

¿Qué claims mínimos necesito?
sub (identificador), y según tu caso email/email_verified. El resto, pídelo cuando realmente aporte valor.

¿Debo validar también el Access Token?
Si tu app consume APIs propias, valida el Access Token en la API (audiencia, firma, expiración). Pero para identidad visual/UX, confía en el ID Token o /userinfo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *