Guía de integración
Conecta una app sin entregar contraseñas.
Esta guía describe el perfil OIDC de FEX-LOGIN. Está pensada para una integración backend-first y para SPAs que mantengan el verificador sólo durante la transacción.
01 · Antes de empezar
Registra la aplicación
- Entra en la consola de apps con una cuenta FEXMAX.
- Registra cada redirect URI HTTPS exacta. No se permiten comodines.
- Usa un cliente público con
token_endpoint_auth_method: none; no hay client secret. - La aplicación queda pending hasta la aprobación de su propietario.
Para URI pairwise, mantén el mismo host cuando necesites continuidad del identificador sub. En producción usa HTTPS; los ejemplos locales deben adaptarse a la política de tu entorno.
02 · Autorización
Genera valores nuevos en cada intento
Usa state y nonce aleatorios y únicos. PKCE S256 es obligatorio: genera un verificador, calcula su challenge y conserva el verificador en una sesión de servidor (preferido) o temporalmente en sessionStorage para una SPA.
const bytes = (n) => crypto.getRandomValues(new Uint8Array(n));
const base64url = (bytes) => btoa(String.fromCharCode(...bytes))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
const verifier = base64url(bytes(32));
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
const challenge = base64url(new Uint8Array(digest));
const state = base64url(bytes(24));
const nonce = base64url(bytes(24));
const params = new URLSearchParams({
response_type: 'code', client_id: 'CLIENT_ID',
redirect_uri: 'https://app.example/callback', scope: 'openid email',
code_challenge: challenge, code_challenge_method: 'S256', state, nonce
});
const authUrl = 'https://ai.fexmax.app/fexmax-login/oauth2/authorize?' + params; // redirige al usuarioNo pongas tokens, secretos, códigos ni verificadores en una URL permanente, en logs o en almacenamiento persistente. El callback debe comprobar state antes de canjear el código.
03 · Contrato
Issuer y endpoints
El issuer es https://ai.fexmax.app/fexmax-login. El documento de descubrimiento está en https://ai.fexmax.app/fexmax-login/.well-known/openid-configuration.
/oauth2/authorize/oauth2/token/oauth2/userinfo/oauth2/revoke/jwksCada ruta anterior lleva el prefijo del issuer. Sólo se admiten openid y email. El claim email_verified no se afirma como true. El claim email es opcional y sólo aparece con consentimiento.
04 · Intercambio y uso
Ejemplos funcionales
Canjea el código una sola vez antes de sus 60 segundos de vida:
curl -X POST 'https://ai.fexmax.app/fexmax-login/oauth2/token' \ -H 'content-type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'client_id=CLIENT_ID' \ --data-urlencode 'code=CODE_RECIBIDO' \ --data-urlencode 'redirect_uri=https://app.example/callback' \ --data-urlencode 'code_verifier=VERIFIER_GENERADO'
Consulta UserInfo con el access token para obtener la identidad autorizada y ayudar a validar revocación:
curl 'https://ai.fexmax.app/fexmax-login/oauth2/userinfo' \ -H 'Authorization: Bearer ACCESS_TOKEN'
Revoca un token cuando la sesión o autorización deba terminar:
curl -X POST 'https://ai.fexmax.app/fexmax-login/oauth2/revoke' \ -H 'content-type: application/x-www-form-urlencoded' \ --data-urlencode 'token=ACCESS_TOKEN' \ --data-urlencode 'client_id=CLIENT_ID'
HttpOnly, Secure y una política adecuada cuando tu arquitectura lo permita.05 · Validación obligatoria
Valida con una librería mantenida
- En el callback, valida
statey rechaza valores ausentes o repetidos. - Valida en el ID token el issuer exacto, la audiencia, la firma mediante JWKS,
expynonce. - Comprueba que el redirect URI usado en el canje coincide exactamente con el registrado.
- Usa una librería OIDC mantenida, como
joseuopenid-client; no implementes criptografía ni validación JWT manualmente. - Los ID tokens no son una sesión eterna: offline sólo valen hasta su expiración de 300 segundos. No hay refresh tokens en este perfil.
Los valores sub son pairwise por host. Trata el email como dato opcional y no asumas que está verificado.
Referencia rápida
Perfil v1
Permitido: authorization_code, PKCE S256, openid, email.
No disponible: profile, offline_access, password, implicit, refresh, client credentials y device flow.