Vas a tener este flujo funcionando.
- Generar state, code_verifier y code_challenge S256.
- Intercambiar el authorization code una sola vez.
- Rotar refresh tokens y revocar la conexión completa.
Seguí el contrato en este orden.
Registrá la aplicación
Configurá las Redirect URI exactas desde Integraciones y API. Un cliente público no guarda Client Secret.
Iniciá la autorización
Redirigí al usuario a /oauth/authorize.php con response_type=code, client_id, redirect_uri, scope, state y PKCE S256.
Intercambiá el código
Tu backend o aplicación nativa llama a /oauth/token.php con grant_type=authorization_code y el code_verifier original.
Rotá y revocá
Cada refresh devuelve un par nuevo. Reutilizar un refresh consumido revoca la familia completa por seguridad.
Superficie utilizada.
/oauth/authorize.php
Consentimiento y emisión del código
/oauth/token.php
Canjear código o rotar refresh
/oauth/revoke.php
Revocar token o conexión
# El navegador visita /oauth/authorize.php con PKCE S256.
# Después del callback, el servidor canjea el código:
curl -sS -X POST \
"https://pietrocal.com/oauth/token.php" \
-H "Accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=TU_CLIENT_ID" \
--data-urlencode "code=CODIGO_RECIBIDO" \
--data-urlencode "redirect_uri=https://tu-app.example/callback" \
--data-urlencode "code_verifier=VERIFICADOR_ORIGINAL"
# Para renovar, persistí el refresh nuevo y descartá el anterior:
curl -sS -X POST \
"https://pietrocal.com/oauth/token.php" \
-H "Accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=refresh_token" \
--data-urlencode "client_id=TU_CLIENT_ID" \
--data-urlencode "refresh_token=REFRESH_TOKEN_VIGENTE"
Lista de verificación.
- Compará state con valor constante y de un solo uso.
- Usá code_challenge_method=S256; no uses plain.
- Persistí el refresh token nuevo antes de descartar el anterior.
- Nunca expongas Client Secret ni refresh tokens en el navegador.
Tratamiento mínimo.
invalid_grantEl código venció, ya fue usado o el code_verifier no coincide.
invalid_clientEl cliente, secreto o tipo de autenticación no coincide con el registro.
invalid_scopeLa solicitud incluye un scope no permitido para la aplicación.
429Los endpoints OAuth tienen límites propios; respetá Retry-After.