Scopes y claims de OpenID Connect
Qué datos de la persona recibes en el id_token y en /api/oauth/userinfo según los scopes openid, profile y email, y cómo verificarlos.
Actualizado el . 3 min de lectura
OpenID Connect es la capa de identidad sobre OAuth: con ella tu aplicación sabe quién ha iniciado sesión. UTILIA OS te lo dice de dos formas, con el mismo contenido: el id_token, un JWT firmado que llega al canjear el código, y el endpoint GET /api/oauth/userinfo. Lo que incluyen depende de tres scopes.
Scopes de identidad
| Scope | Claims que añade |
|---|---|
openid | Hace que se emita el id_token y da sub, el identificador de la persona |
profile | name, given_name, family_name y picture (solo si la persona tiene foto) |
email | email y email_verified |
No dependen de los permisos de la persona ni del plan de su organización, y en la pantalla de consentimiento no se pueden desactivar. Si no pides ningún scope y el registro de tu cliente no define otros, se piden estos tres.
Claims del id_token
| Claim | Tipo | Scope | Descripción |
|---|---|---|---|
iss | string | openid | Emisor: https://os.utilia.ai |
sub | string | openid | Identificador de la persona (UUID). Es estable: úsalo como clave en tu base de datos |
aud | string | openid | El client_id de tu aplicación |
exp | number | openid | Caducidad, una hora después de la emisión (segundos desde 1970) |
iat | number | openid | Momento de emisión |
at_hash | string | openid | Resumen del access token emitido a la vez |
nonce | string | openid | El nonce que enviaste en la autorización, si lo enviaste |
name | string | profile | Nombre completo |
given_name | string | profile | Nombre |
family_name | string | profile | Apellidos |
picture | string | profile | Dirección de la foto de perfil |
email | string | email | Correo |
email_verified | boolean | email | Siempre true |
{
"iss": "https://os.utilia.ai",
"sub": "3b1f6c2e-8a4d-4f0b-9c7e-2d5a1e6f8b90",
"aud": "utilia_5e2a9c4d7b1f3e6a8c0d2f4b6a8e1c3d",
"exp": 1743638400,
"iat": 1743634800,
"at_hash": "Qx2mN8pL4vR7tY1wZ5kB3c",
"nonce": "n-0S6_WzA2Mj",
"name": "María García",
"given_name": "María",
"family_name": "García",
"email": "maria@ejemplo.com",
"email_verified": true
}El id_token solo llega en el canje del código, no en las renovaciones con el refresh token. Si necesitas datos actualizados de la persona más adelante, pídelos a userinfo.
Verificar el id_token
Está firmado con RS256. Valídalo en este orden y descártalo en cuanto falle una comprobación:
Validar un id_token
/api/oauth/jwks
Firma
Con la clave cuyo kid coincide con el de la cabecera del token.Si no: descártalo.
iss y aud
Emisor y destinatario
iss es https://os.utilia.ai (se abre en una pestaña nueva) y aud es tu client_id.Si no: descártalo.
exp
Caducidad
Una hora después de la emisión.Si no: descártalo.
nonce · Opcional
Nonce
Si lo enviaste en la autorización, tiene que coincidir.Si no: descártalo.
Las bibliotecas OpenID Connect (Auth.js, Authlib, oidc-client-ts) hacen todo esto solas a partir de https://os.utilia.ai/.well-known/openid-configuration.
Endpoint userinfo
/api/oauth/userinfoDatos de la persona dueña del access token
Acepta GET y POST, con el access token en la cabecera Authorization: Bearer. El token tiene que incluir openid; si no, o si ha caducado o está revocado, responde 401. Devuelve los mismos datos que el id_token, sin los claims técnicos (iss, aud, exp, iat, at_hash, nonce):
{
"sub": "3b1f6c2e-8a4d-4f0b-9c7e-2d5a1e6f8b90",
"name": "María García",
"given_name": "María",
"family_name": "García",
"email": "maria@ejemplo.com",
"email_verified": true
}Endpoints de descubrimiento
| Dirección | Para qué |
|---|---|
https://os.utilia.ai/.well-known/openid-configuration | Documento con todas las direcciones y capacidades |
https://os.utilia.ai/api/oauth/jwks | Claves públicas para verificar la firma (también en /.well-known/jwks.json) |
https://os.utilia.ai/api/oauth/userinfo | Datos de la persona |
https://os.utilia.ai/api/oauth/logout | Cierre de sesión iniciado por tu aplicación |
El detalle de cada documento está en Descubrimiento del servidor. Siguiente paso: Iniciar sesión con UTILIA en Next.js o en Flask.