01 nov 2025·4 min de lectura

Arreglar inicio de sesión OAuth roto en apps generadas por IA (producción)

Repara un inicio de sesión OAuth roto en apps generadas por IA encontrando desajustes de redirect URI, errores en callbacks, validación de state faltante y problemas de cookies en producción.

Arreglar inicio de sesión OAuth roto en apps generadas por IA (producción)

¿Qué es lo que realmente falla cuando OAuth falla en producción?

Los fallos de OAuth resultan confusos porque tu código a menudo parece correcto. El proveedor hace lo que le pediste, pero una pequeña discrepancia entre local y producción hace que el handshake falle.

“Funciona en local pero falla en producción” suele verse así: pulsas Google o GitHub, vuelves a tu app y te encuentras con una página en blanco, un 401/403, o un bucle infinito que vuelve al botón de login. A veces el proveedor muestra un error claro (a menudo sobre la URL de redirección). Otras veces parece exitoso, pero la app olvida inmediatamente quién eres tras el callback.

OAuth es quisquilloso porque depende de URLs exactas y reglas del navegador. El proveedor compara tu redirect URI con lo que registraste. Tu app tiene que leer el callback, validar el estado del login y establecer una cookie de sesión que el navegador realmente enviará en la siguiente petición. Pequeñas diferencias como http vs https, www vs sin www, o un flag de cookie pueden ser la diferencia entre “conectado” y “¿quién eres?”.

Síntomas comunes en producción:

  • El proveedor se queja de un redirect URI mismatch
  • El callback llega a tu app pero luego redirige en círculos
  • El login funciona una vez y luego los usuarios se desconectan al refrescar
  • Solo algunos usuarios fallan (a menudo Safari, iOS o modo incógnito)
  • Errores que aparecen solo detrás de un proxy o en el dominio real

Las apps generadas por IA suelen cablear la autenticación de forma frágil: URLs de callback hardcodeadas, comprobaciones de estado faltantes y configuraciones de cookies que pasan en local pero fallan bajo HTTPS real, dominios reales y las políticas de privacidad modernas de los navegadores.

Mapea tu flujo de login antes de cambiar nada

La forma más rápida de perder tiempo es empezar a tocar ajustes al azar sin un mapa claro. OAuth es una cadena. Una suposición equivocada sobre qué URL se usa, dónde vive la sesión o dónde se termina HTTPS puede romper todo el flujo.

Anota el flujo exacto en producción (no lo que asumes desde local). Muchas apps generadas por IA cambian las URLs base según variables de entorno, y algunas tienen múltiples rutas de callback (Google vs GitHub, web vs móvil).

Captura estos detalles para poder comparar local vs staging vs producción:

  • Origen del frontend (lo que carga el navegador) y origen de la API (a donde van las peticiones)
  • La URL de callback que tu app recibe después de que el proveedor redirige de vuelta
  • La redirect URI registrada en el proveedor OAuth (cadena exacta)
  • Dónde se almacena la sesión (cookie, token en localStorage o sesión en servidor)
  • Tu configuración de edge (reverse proxy/CDN) y dónde HTTPS se vuelve HTTP

Chequeo de realidad: si tu proxy termina HTTPS, tu servidor de app puede ver las peticiones como http a menos que las cabeceras reenviadas estén configuradas correctamente. Eso puede cambiar las callback URIs generadas y los flags de seguridad de las cookies.

Ejemplo: en local funciona porque todo es http://localhost en un dominio. En producción, el frontend está en app.example.com, la API en api.example.com, y el callback cae en el host incorrecto. El proveedor redirige con éxito, pero la cookie de sesión se escribe para el dominio de la API y nunca llega al frontend. Resultado: un bucle de “desconectado”.

Desajustes en la redirect URI: la forma más rápida de romper el login social

Si necesitas una victoria rápida, empieza por la redirect URI. Un carácter de diferencia y el proveedor bloqueará el callback.

La mayoría de proveedores requieren una coincidencia exacta, incluyendo:

  • Esquema (http vs https)
  • Dominio (www vs sin www, subdominios)
  • Ruta (incluida la barra final)
  • Parámetros de consulta (presentes, ausentes o con distinto orden)
  • Puerto (común en dev local)

Los problemas en producción a menudo vienen de mezclar entornos. Probaste con un dominio de staging y luego lanzaste con un dominio personalizado, pero el proveedor solo permite la callback de staging. Otro caso común es una herramienta que genera múltiples URLs de despliegue (builds de preview, URLs temporales), y la app construye accidentalmente el callback usando la incorrecta.

Los proxies pueden empeorar esto. Si tu app piensa que está en http, puede generar una redirect URI en http mientras el sitio real es https. En producción, eso aparece como un error del proveedor tipo “redirect_uri mismatch” o una página en blanco tras el login.

Ejemplo simple: local usa http://localhost:3000/auth/callback, pero en producción debería ser https://app.yourdomain.com/auth/callback (sin barra final). Si tu código sale como https://app.yourdomain.com/auth/callback/, algunos proveedores lo tratan como una URL distinta y la rechazan.

Manejo de callbacks defectuoso y bucles de redirección

Get an OAuth fix roadmap
Receive a practical fix plan for redirect mismatch, PKCE, and session storage issues.

Al final de OAuth, el proveedor devuelve al usuario a tu app con la prueba de que inició sesión. Si tu ruta de callback se trata como una ruta de página normal, errores pequeños pueden convertirse en bucles o en fallos tipo “funciona localmente, falla en producción”.

Qué debería hacer la ruta de callback

Un endpoint de callback debe ser corto y aburrido. Si intenta renderizar UI, obtener datos del usuario primero o pasar por tu router normal con guardias de auth, es fácil crear un bucle.

Un handler de callback sano hace esto:

  • Leer la respuesta del proveedor (code, state y cualquier campo error).
  • Intercambiar el código por tokens (server-side) y validar la respuesta.
  • Crear o reanudar una sesión (establecer las cookies correctas) y almacenar la identidad del usuario.
  • Redirigir a una página segura de “estás conectado”.

Un bug común en código generado por IA es cargar la app completa en el callback. El guardia de auth de la app ve “aún no autenticado” y redirige inmediatamente al proveedor, creando un bucle.

Maneja los errores del proveedor sin fallar

Los proveedores devuelven con regularidad errores como access_denied (el usuario canceló) o invalid_grant (el código expiró o ya fue usado). Si tu código asume que siempre habrá un code, provocas un 500, el frontend reintenta y el bucle continúa.

Mantén el manejo de errores simple:

  • Si existe error, muestra un mensaje amigable y ofrece un botón “Intentar de nuevo”.
  • Si el intercambio de tokens falla, registra un error saneado y detén el flujo.
  • No reuses el mismo auth code en un reintento. Comienza un login nuevo.

También vigila las redirecciones post-login. Muchas apps aceptan un returnTo en la query y redirigen ciegamente a él. Eso puede causar rutas rotas (redirigiendo de nuevo a /auth/callback) y riesgo de open-redirect. Permite solo paths del mismo sitio, usa un valor por defecto conocido y limpia lo sospechoso.

Falta de validación del state y por qué falla de forma intermitente

El valor state es una etiqueta de seguridad que tu app crea antes de enviar a alguien a Google, GitHub u otro proveedor. Cuando el proveedor redirige de vuelta, tu app debe verificar que el state devuelto coincida con el que emitiste. Eso bloquea ataques CSRF y confirma que el callback pertenece a la misma sesión del navegador.

Cuando state falta, se almacena incorrectamente o no se valida, a menudo se ve así:

  • Errores de “Invalid state” o “CSRF detected” que los usuarios no pueden reproducir
  • El login funciona una vez y luego falla en el siguiente intento
  • Los usuarios se autentican y luego se desconectan inmediatamente tras el callback
  • Reportes tipo “funciona en mi laptop, pero no en producción”

Por qué se vuelve intermitente en producción: state debe sobrevivir entre la redirección inicial y el callback. Las apps suelen almacenarlo en una sesión de servidor (memoria, Redis, base de datos) o en una cookie de corta duración.

Si se guarda en la memoria del servidor, la producción falla en cuanto tienes más de una instancia. La petición inicial puede golpear el servidor A, mientras que el callback golpea el servidor B. El servidor B nunca vio ese state.

Si se guarda en una cookie, la configuración de producción puede descartarla silenciosamente: Secure ausente bajo HTTPS, dominio de cookie equivocado, o SameSite que la bloquea en la redirección cross-site.

También revisa PKCE. Para muchos proveedores, clientes públicos (SPAs, móviles y algunos setups “sin backend”) deben usar PKCE: la app crea un code_verifier, lo hashea a code_challenge y luego lo prueba durante el intercambio de tokens. Si PKCE falta o no coincide, las fallas pueden aparecer solo en ciertos dispositivos o navegadores.

Problemas con cookies: SameSite, Secure, domain y path

Repair AI-generated OAuth code
FixMyMess turns fragile AI-generated auth code into production-ready implementation.

Muchos fallos de OAuth son en realidad fallos de cookies. Tu app establece una cookie de sesión (o una cookie temporal para el flujo OAuth), pero el navegador no la envía de vuelta en el callback. El proveedor está bien, pero tu app no puede reconectar al usuario con una sesión.

SameSite: por qué los callbacks se comportan distinto

Los flujos OAuth saltan entre sitios (tu app -> proveedor -> tu app).

Con SameSite=Lax, las cookies se envían en muchas navegaciones top-level, pero aparecen casos límite con callbacks mediante POST, iframes o vistas web personalizadas. Si tu flujo realmente necesita cookies en un callback cross-site, a menudo necesitas SameSite=None.

Si pones SameSite=None, también debes marcar Secure, o los navegadores modernos ignoran la cookie.

Secure, domain y path: ajustes pequeños, gran impacto

Producción corre en HTTPS y generalmente en dominios reales en lugar de localhost. Revisa esto:

  • Secure está activado en HTTPS y no se exige por error en HTTP en dev local.
  • El Domain de la cookie coincide con lo que el navegador ve (ojo con app.example.com vs example.com).
  • El Path de la cookie no es demasiado restrictivo (por ejemplo /api cuando tu callback llega a /auth/callback).
  • Las cookies no se sobrescriben en la redirección con ajustes distintos.
  • El callback no se sirve desde un subdominio distinto al que se estableció la cookie.

Los errores CORS son ruidosos. Los errores de cookies son silenciosos. Una buena pista: si la llamada de red tiene éxito (200/302) pero el usuario sigue desconectado, normalmente son cookies y no CORS.

Finalmente, los navegadores embebidos (webviews) y las nuevas restricciones sobre cookies de terceros pueden romper el login social de formas que no reproduces en desktop Chrome. Prueba en el dispositivo y entorno reales que usan tus usuarios.

Preguntas Frecuentes

Why does OAuth work locally but fail in production?

Comienza comparando la URI de redirección exacta que tu app envía con la URI de redirección exacta guardada en la configuración del proveedor. Una diferencia de un carácter puede romperlo, incluyendo https vs http, www vs sin www, una barra final, o un parámetro de consulta extra.

Si no estás seguro de qué está enviando tu app en producción, captura la URL final usada durante la redirección de login y trátala como la fuente de la verdad.

What does “redirect_uri_mismatch” actually mean, and what’s the fastest fix?

Normalmente significa que el proveedor rechaza el callback porque la redirect URI no coincide exactamente con la que registraste. Arregla la discrepancia primero y vuelve a probar antes de cambiar otra cosa.

Si el error desaparece pero sigues desconectado, el siguiente problema probable es que la cookie de sesión no se esté creando o no se envíe de vuelta después del callback.

How can a reverse proxy or CDN break OAuth even if my code is correct?

Cuando HTTPS se termina en un proxy o load balancer, tu servidor de aplicaciones puede ver la petición como HTTP a menos que las cabeceras reenviadas estén configuradas correctamente. Eso puede hacer que la app genere una redirect URI en http o que establezca cookies sin las marcas de seguridad adecuadas.

La solución práctica es hacer que tu app conozca el esquema y host originales para generar el callback correcto en https y las cookies adecuadas en producción.

Why do I get an endless redirect loop after the provider sends users back?

Un bucle de redirección suele ocurrir cuando la ruta de callback se trata como una página protegida normal. Tu app pregunta “¿estoy autenticado?” antes de haber creado la sesión, y vuelve a redirigir al proveedor.

Mantén el handler de callback sencillo: procesa la respuesta del proveedor, crea la sesión y redirige una sola vez a una página normal.

If login looks successful, why does my app immediately forget the user?

Porque el proveedor devuelve a tu sitio desde un origen distinto y los navegadores modernos aplican reglas estrictas sobre cookies. Si tu cookie de sesión o la cookie temporal del flujo OAuth no se envía en el callback, la app no puede reconectar el navegador con el intento de login.

La mayoría de arreglos en producción implican ajustar SameSite y Secure correctamente, además de verificar dominio y path de la cookie.

What is the OAuth “state” value, and why does it fail intermittently?

state es un valor de seguridad por intento que tu app genera y debe verificar al regresar. Si falta, se almacena mal o no se valida, verás errores de “invalid state” o comportamiento intermitente difícil de reproducir.

No desactives las comprobaciones de state para “hacer que funcione”. Arregla el almacenamiento y la verificación para que el callback sea confiable y consistente.

Why does OAuth break only after I scale to multiple instances?

Si guardas el estado de login solo en la memoria del servidor, deja de funcionar en cuanto tienes más de una instancia. La petición inicial puede llegar al servidor A y el callback al servidor B, que nunca vio ese state.

Usa un almacén de sesiones compartido o una cookie de corta duración que funcione entre instancias y vuelve a probar con varias instancias habilitadas.

Do I need PKCE, and what does it break when it’s wrong?

PKCE es un paso de verificación usado por muchos proveedores para proteger los códigos de autorización, especialmente para SPAs y clientes móviles. Si el verifier/challenge falta o no coincide, el intercambio de tokens falla aunque la redirección del proveedor parezca correcta.

Si las fallas aparecen más en ciertos navegadores o dispositivos, los desajustes de PKCE son un culpable común para revisar pronto.

Why does OAuth fail only on Safari, iOS, or incognito mode?

Safari, iOS, modo incógnito y webviews embebidos pueden imponer reglas de cookies y seguimiento más estrictas. Eso puede impedir que las cookies se creen o se envíen durante la redirección cross-site, haciendo que falle la validación del state o la creación de la sesión.

Prueba en el dispositivo y entorno reales que usan tus usuarios, no solo en desktop Chrome, y enfoca la depuración en cookies y persistencia de estado.

What should I log or check first to diagnose a broken production OAuth flow?

Registra solo lo necesario para localizar el paso que falla sin exponer secretos. Captura marcas de tiempo, proveedor usado, si recibiste un error o un code, si la validación de state pasó, y un código de error interno simple para fallos en el intercambio de tokens.

Si tu código de auth fue generado por IA y está enredado, FixMyMess puede ejecutar una auditoría de código gratuita, identificar la causa exacta y normalmente estabilizar el login en producción en 48–72 horas, o reconstruir el flujo de auth cuando ya no merece la pena parchearlo.