Tu primer token en cinco minutos
Registra un cliente, genera PKCE, autoriza y canjea el código: de cero a un access token de UTILIA OS con curl, JavaScript o Python.
Actualizado el . 3 min de lectura
Esta guía te lleva de cero a un access token funcional sin salir de la página. Solo necesitas una cuenta de UTILIA OS con la que autorizar y curl o cualquier cliente HTTP. Al final comprobarás el token pidiendo los datos de la persona a GET /api/oauth/userinfo. Antes de empezar, retén estos tres plazos: marcan cuánto tiempo tienes en cada paso.
Tres plazos que vas a usar
- Código de autorización
- 60segundos
- Sirve una sola vez: canjéalo nada más recibirlo.
- Access token
- 1hora
- Después, renuévalo con el refresh token.
- Refresh token
- 90días
- Desde la autorización. Cambia en cada renovación.
El orden completo de la conversación entre tu aplicación, el navegador y UTILIA OS está dibujado en Flujo de autorización.
Registra tu aplicación
Envía una petición al endpoint de registro dinámico. Es público y no necesita autenticación.
POST/api/oauth/registerRegistro dinámico de clientes OAuth (público)
curl -X POST https://os.utilia.ai/api/oauth/register \ -H "Content-Type: application/json" \ -d '{ "client_name": "Mi app de prueba", "redirect_uris": ["http://localhost:3000/callback"] }'Respuesta:
JSON{ "client_id": "mcp_3f9a1c2b7d4e5f60718293a4b5c6d7e8", "client_id_issued_at": 1743897600, "redirect_uris": ["http://localhost:3000/callback"], "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "token_endpoint_auth_method": "none", "client_name": "Mi app de prueba" }Con
token_endpoint_auth_method: "none"el cliente es público y no tiene secreto: PKCE lo protege. Las direcciones de vuelta deben usarhttps, salvolocalhost,127.0.0.1y[::1], que admitenhttp. Si prefieres crear la aplicación desde la interfaz, con clave secreta y enlaces legales, sigue Activar OAuth en tu aplicación.Genera el par PKCE
Crea un
code_verifieraleatorio y deriva de él elcode_challengecon SHA-256 en Base64URL sin relleno.CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=' | tr '/+' '_-') CODE_CHALLENGE=$(printf '%s' "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr -d '=' | tr '/+' '_-') echo "code_verifier: $CODE_VERIFIER" echo "code_challenge: $CODE_CHALLENGE"Guarda el
code_verifier: lo necesitarás en el paso 5. Nunca viaja en la URL de autorización.Abre la URL de autorización
Monta la URL con estos parámetros y ábrela en el navegador. Los espacios de
scopevan codificados como%20.https://os.utilia.ai/api/oauth/authorize?client_id=CLIENT_ID&redirect_uri=http://localhost:3000/callback&response_type=code&code_challenge=CODE_CHALLENGE&code_challenge_method=S256&scope=openid%20profile%20email&state=VALOR_ALEATORIO- client_idstringobligatorio
- El identificador del paso 1.
- redirect_uristringobligatorio
- Una de las direcciones registradas, exactamente igual.
- response_typestringobligatorio
- Siempre code.
- code_challengestringobligatorio
- El challenge del paso 2.
- code_challenge_methodstringobligatorio
- Siempre S256. No se admite plain.
- scopestring
- Scopes separados por espacios. Si lo omites, se piden solo openid, profile y email.
- statestring
- Valor aleatorio contra la falsificación de peticiones. Vuelve tal cual en la redirección.
UTILIA OS pide a la persona que inicie sesión, si no lo ha hecho, y le muestra la pantalla de consentimiento.
Recoge el código
Cuando la persona autoriza, UTILIA OS la devuelve a tu
redirect_uricon el código:http://localhost:3000/callback?code=abc123def456&state=VALOR_ALEATORIOComprueba que
statecoincide con el que enviaste y quédate concode. Tienes 60 segundos para canjearlo.Canjea el código por tokens
POST/api/oauth/tokenCanje del código por tokens
El endpoint admite
application/x-www-form-urlencoded(lo habitual en OAuth) y JSON.curl -X POST https://os.utilia.ai/api/oauth/token \ -H "Content-Type: application/x-www-form-urlencoded" \ -d 'grant_type=authorization_code' \ -d 'code=AUTH_CODE' \ -d 'redirect_uri=http://localhost:3000/callback' \ -d 'code_verifier=CODE_VERIFIER' \ -d 'client_id=CLIENT_ID'Respuesta:
JSON{ "access_token": "TU_ACCESS_TOKEN", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "TU_REFRESH_TOKEN", "scope": "openid profile email", "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Im9pZGMtcHJvZC0xIn0..." }Cada vez que renuevas, recibes un refresh token nuevo y el anterior deja de valer: guarda siempre el último. Lo explica Rotación del refresh token.
Usa el token
Pide los datos de la persona:
GET/api/oauth/userinfoDatos de la persona autenticada (access token con openid)
curl -H "Authorization: Bearer ACCESS_TOKEN" \ https://os.utilia.ai/api/oauth/userinfoRespuesta:
JSON{ "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 }Si la persona tiene foto de perfil, también llega
picture. Para trabajar con sus datos, pide en el paso 3 los scopes de un servidor MCP junto con suresourcey llama a ese servidor con el token. Lo tienes en Scopes y recursos.
Si algo falla
invalid_grant: el código ha caducado, ya se usó o elcode_verifierno corresponde alcode_challenge. Genera un par PKCE nuevo y vuelve al paso 3.invalid_grantconredirect_uri mismatch: la dirección del canje no es idéntica a la de la autorización.http://localhost:3000/callbackyhttp://localhost:3000/callback/son distintas.invalid_requestconcode_verifier is required for PKCE: falta elcode_verifieren el canje.
El resto de casos está en Problemas frecuentes con OAuth.