Flujos de OAuth desde el frontend
Implemente el flujo Authorization Code con PKCE en una SPA, intercambie el código por tokens, almacene los tokens de acceso de forma segura y evite el flujo implícito.
Flujos de OAuth desde el frontend es una lección gratuita de Frontend Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Frontend Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Frontend Academy incluye 4 lecciones en total.
¿Qué es OAuth?
OAuth 2.0 es un protocolo de delegación: su aplicación obtiene permiso para actuar en nombre del usuario en un servicio de terceros (Google, GitHub, etc.) sin llegar a ver la contraseña del usuario. Se utiliza en «Iniciar sesión con Google», las aplicaciones OAuth de GitHub y la mayoría de los sistemas modernos de autenticación.
Roles principales
Propietario del recurso: el usuario. Cliente: su aplicación. Servidor de autorización: el proveedor de OAuth (Google, Auth0). Servidor de recursos: la API protegida por el token de acceso.
El flujo de código de autorización
El flujo estándar y seguro para aplicaciones del lado del servidor: 1) Redirigir al usuario al inicio de sesión del proveedor. 2) El usuario inicia sesión y da su consentimiento. 3) El proveedor redirige de vuelta con un code. 4) El servidor intercambia el código por un access token (secreto exclusivo del servidor).
Por qué se necesita PKCE en las SPA
Las SPA no pueden mantener un secreto de cliente, ya que estaría en el paquete del navegador. PKCE (Proof Key for Code Exchange) sustituye el secreto por un verificador y un desafío de código generados para cada solicitud. Ahora es el estándar para todos los clientes públicos de OAuth.
El flujo de PKCE paso a paso
1) Genere un code_verifier aleatorio. 2) Calcule su hash SHA-256 = code_challenge. 3) Redirija a /authorize con el desafío. 4) Tras el consentimiento, reciba un código. 5) Intercambie el código y el verificador por un token de acceso. El proveedor verifica que desafío = hash(verificador).
Generación del verificador y el desafío de código
El verificador es una cadena aleatoria; el desafío es su valor codificado en base64 compatible con URL después de aplicar SHA-256.
function base64url(arr) {
return btoa(String.fromCharCode(...arr))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}
async function generatePKCE() {
const arr = new Uint8Array(32);
crypto.getRandomValues(arr);
const verifier = base64url(arr);
const hash = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));
const challenge = base64url(new Uint8Array(hash));
return { verifier, challenge };
}Redirección al proveedor
Construya la URL de autorización con el desafío, el estado (protección contra CSRF) y los ámbitos.
const { verifier, challenge } = await generatePKCE();
const state = crypto.randomUUID();
sessionStorage.setItem('pkce_verifier', verifier);
sessionStorage.setItem('oauth_state', state);
const url = new URL('https://accounts.google.com/o/oauth2/v2/auth');
url.searchParams.set('client_id', CLIENT_ID);
url.searchParams.set('redirect_uri', `${origin}/auth/callback`);
url.searchParams.set('response_type', 'code');
url.searchParams.set('scope', 'openid email profile');
url.searchParams.set('code_challenge', challenge);
url.searchParams.set('code_challenge_method', 'S256');
url.searchParams.set('state', state);
window.location.href = url.toString();Gestión de la devolución de llamada
El proveedor redirige a su URL de devolución de llamada con ?code=...&state=.... Verifique el estado para evitar CSRF y, después, intercambie el código.
// /auth/callback page:
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const returnedState = params.get('state');
const expected = sessionStorage.getItem('oauth_state');
if (returnedState !== expected) throw new Error('Bad state');
const verifier = sessionStorage.getItem('pkce_verifier');
const tokens = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
client_id: CLIENT_ID,
redirect_uri: `${origin}/auth/callback`,
code_verifier: verifier
})
}).then(r => r.json());
// tokens: { access_token, id_token, refresh_token, expires_in }Almacenamiento seguro de tokens
Práctica recomendada: no almacene tokens de acceso en localStorage, ya que XSS puede robarlos. Opciones: 1) Solo en memoria (se borran al actualizar la página y es necesario volver a autenticarse). 2) Cookie HttpOnly (establecida por su backend después del flujo PKCE, no accesible para JavaScript).
Evite el flujo implícito
El antiguo flujo implícito devuelve el token de acceso directamente en el fragmento de la URL. OAuth 2.0 Security BCP lo ha declarado obsoleto, ya que los tokens se filtran al historial del navegador y a los referentes. Use siempre Código de autorización + PKCE.
Tokens de actualización
Los tokens de acceso caducan (normalmente en una hora). Un token de actualización, con una duración mayor, obtiene nuevos tokens de acceso de forma silenciosa. En las SPA, los tokens de actualización se proporcionan cada vez más mediante cookies HttpOnly; nunca mediante localStorage.
Tokens de ID frente a tokens de acceso
Token de ID (OpenID Connect): JWT que demuestra quién es el usuario. Token de acceso: opaco o JWT, se utiliza para llamar a las API. Verifique la firma y las claims del token de ID (iss, aud, exp, nonce) antes de confiar en él.
Bibliotecas de autenticación
No implemente su propia solución. Use: oidc-client-ts para OIDC sin abstracciones, auth0/spa-js para Auth0, @clerk/clerk-react para Clerk, NextAuth.js/Auth.js para Next y Nuxt-auth para Nuxt. Estas bibliotecas gestionan PKCE, la actualización de tokens y el almacenamiento.
Comprobación rápida
¿Por qué las aplicaciones de una sola página deben usar PKCE (Proof Key for Code Exchange) con el flujo de código de autorización en lugar de usar únicamente el flujo de código de autorización básico?
Resumen: OAuth en el frontend
Código de autorización + PKCE es el estándar moderno para las SPA. Genere un verificador y un desafío S256 para cada solicitud. Redirija a /authorize con el desafío y el estado. Verifique el estado en la devolución de llamada. Intercambie el código y el verificador por tokens. No use nunca el flujo implícito. Prefiera cookies HttpOnly para almacenar tokens. Use bibliotecas (auth0-spa-js, oidc-client-ts, NextAuth); no implemente su propia solución.
Preguntas frecuentes
¿La lección «Flujos de OAuth desde el frontend» es gratis?
Sí — el texto completo de «Flujos de OAuth desde el frontend» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Frontend Academy, actualiza a CoddyKit PRO. El curso de Frontend Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Flujos de OAuth desde el frontend»?
Implemente el flujo Authorization Code con PKCE en una SPA, intercambie el código por tokens, almacene los tokens de acceso de forma segura y evite el flujo implícito. Practicas Frontend Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Frontend Academy?
No se requiere experiencia previa. Frontend Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Flujos de OAuth desde el frontend»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Frontend Academy?
Sí. Cada lección de Frontend Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Prevención de XSS: codificación de salida y CSP
- CSRF: cookies SameSite y tokens
- Content Security Policy: nonce y hash
- Flujos de OAuth desde el frontend