Skip to Content

Flujo Authorization Code + PKCE

El flujo Authorization Code + PKCE es el patrón OAuth 2.0 recomendado para todas las aplicaciones que autentican usuarios reales. Esta página explica qué es PKCE, por qué se introdujo y cómo funciona el flujo completo de principio a fin — incluyendo las propiedades de seguridad en cada paso.

Por qué existe PKCE

El flujo Authorization Code original de OAuth 2.0 (sin PKCE) tiene una vulnerabilidad de seguridad en clientes públicos: la interceptación de código.

Cuando Auris redirige de vuelta a tu aplicación con un código de autorización, ese código viaja a través de la barra de URL del navegador. En dispositivos móviles, una aplicación maliciosa registrada para gestionar el mismo esquema URI personalizado podría interceptar la redirección. Incluso en aplicaciones web, el código puede aparecer en logs de servidor, encabezados de referencia o historial del navegador.

Si un atacante intercepta el código, puede canjearlo por tokens en el endpoint de tokens. En el flujo clásico, nada lo impediría.

PKCE (Proof Key for Code Exchange, RFC 7636) soluciona esto vinculando el código de autorización a la sesión de cliente específica que lo solicitó. Solo el cliente que generó originalmente el code verifier puede canjear el código — incluso si un atacante tiene el código.

Auris aplica PKCE en todos los flujos de código de autorización. El método de desafío plain es rechazado — solo se acepta el método S256 (SHA-256). No hay forma de omitir PKCE en Auris.

El mecanismo PKCE

PKCE añade dos valores al flujo estándar:

Code Verifier: Una cadena aleatoria criptográficamente segura, de 43-128 caracteres, usando solo caracteres URL no reservados (A-Z, a-z, 0-9, -, ., _, ~). Este valor se mantiene secreto por el cliente.

Code Challenge: Una versión transformada del code verifier, calculada como:

code_challenge = BASE64URL(SHA256(ASCII(code_verifier)))

El cliente envía el code challenge (el hash) al endpoint de autorización. Al canjear el código, el cliente envía el code verifier sin procesar. Auris recalcula el challenge y confirma que coincide. Como un atacante no puede revertir un hash SHA-256, no puede falsificar el verifier.

Flujo paso a paso

Paso 1: Generar el Code Verifier

El cliente genera un code_verifier criptográficamente aleatorio. Debe tener entre 43 y 128 caracteres del alfabeto [A-Za-z0-9-._~].

function generateCodeVerifier(): string { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~' const array = new Uint8Array(64) crypto.getRandomValues(array) return Array.from(array) .map(b => chars[b % chars.length]) .join('') } const codeVerifier = generateCodeVerifier() // Ejemplo: "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

Almacena el code_verifier en sessionStorage (no en localStorage) — solo necesita sobrevivir al viaje de redirección.

Paso 2: Derivar el Code Challenge

Calcula SHA-256(code_verifier) y codifica el resultado en Base64URL:

async function generateCodeChallenge(verifier: string): Promise<string> { const encoder = new TextEncoder() const data = encoder.encode(verifier) const digest = await crypto.subtle.digest('SHA-256', data) return btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, '') } const codeChallenge = await generateCodeChallenge(codeVerifier) // Ejemplo: "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

Paso 3: Redirigir al endpoint de autorización

Construye la URL de autorización e inicia la redirección:

GET https://auth.yourdomain.com/api/oauth/authorize ?response_type=code &client_id=app_xxxxx &redirect_uri=https://yourapp.com/callback &scope=openid+profile+email &state=random-csrf-token &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM &code_challenge_method=S256
ParámetroRequeridoDescripción
response_typeSíSiempre code
client_idSíClient ID de tu aplicación
redirect_uriSíDebe coincidir exactamente con una URL de callback registrada
scopeSíDebe incluir openid
stateRecomendadoToken CSRF aleatorio para prevenir ataques CSRF
code_challengeSíEl hash SHA-256 Base64URL del code verifier
code_challenge_methodSíSiempre S256

Paso 4: El usuario se autentica

Auris muestra la página de login alojada. El usuario introduce sus credenciales, completa cualquier factor MFA requerido y aprueba los scopes solicitados.

Paso 5: Auris redirige de vuelta con el código

Tras la autenticación exitosa, Auris redirige al redirect_uri con un código de autorización de un solo uso:

https://yourapp.com/callback?code=auth_code_xyz&state=random-csrf-token

Paso 6: Intercambiar el código por tokens

El cliente envía el código más el code verifier original al endpoint de tokens:

POST /api/auth/token HTTP/1.1 Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=auth_code_xyz &redirect_uri=https://yourapp.com/callback &client_id=app_xxxxx &code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

Auris recalcula el code challenge desde el verifier y lo compara con el challenge almacenado. Si coinciden, emite los tokens.

Paso 7: Recibir los tokens

{ "access_token": "eyJhbGciOiJSUzI1NiJ9...", "token_type": "Bearer", "expires_in": 900, "refresh_token": "rt_7fKp2mXa9qN3vB8yR4tL1wC6jD5sE0uH", "id_token": "eyJhbGciOiJSUzI1NiJ9...", "scope": "openid profile email" }

Los SDK de Auris (JavaScript, React, Next.js, PHP) gestionan todos los pasos de generación de PKCE, almacenamiento del verifier, intercambio de código y gestión de tokens automáticamente. Solo necesitas llamar a loginWithRedirect() y handleRedirectCallback().