Angular · Nginx · FastAPI · Seguridad

Configuracion recomendada para que una API no quede expuesta al frontend publico

Cuando una aplicacion Angular habla directamente con un backend, cualquier credencial que viaje al navegador termina expuesta. La solucion correcta no es esconder mejor la clave, sino mover la confianza al lado servidor.

Esta guia resume el patron aplicado: Angular llama al dominio principal de la web, Nginx reenvia la peticion a una API privada y FastAPI solo acepta peticiones que lleguen con una cabecera interna inyectada por el proxy.

La idea central

Un secreto solo es secreto si nunca llega al navegador. Si Angular lo envia, el secreto ya se ha perdido.

1. Por que el login directo desde frontend es mala idea

Una cuenta tecnica compartida dentro del bundle del frontend puede extraerse del JavaScript compilado, del panel de red o del propio codigo fuente. Eso significa que el backend queda publico de facto aunque exija token.

Este problema aparece mucho cuando el frontend pide un token con usuario y contraseña fijos y luego reutiliza ese bearer en todas las peticiones.

2. Arquitectura recomendada

La solucion practica consiste en separar el flujo entre frontend publico, reverse proxy confiable y API protegida.

Diagrama del flujo recomendado: navegador al dominio principal, proxy Nginx a la API privada y FastAPI validando una cabecera interna.
Frontend publico

Angular solo habla con el dominio principal del sitio. No guarda credenciales privadas del backend.

Reverse proxy confiable

Nginx añade una cabecera interna que solo existe en el lado servidor.

API protegida

FastAPI rechaza llamadas directas salvo que la cabecera interna coincida con el secreto esperado.

Resultado

La API sigue sirviendo a la web, pero ya no puede reutilizarse directamente por terceros solo con abrir DevTools.

3. Flujo recomendado en Nginx

Una forma limpia de exponer la funcionalidad es publicar una ruta dedicada como /api/servicio-interno/ en el dominio principal y redirigirla al host privado de la API.

server {
    server_name example.com;

    location ^~ /api/internal-service/ {
        proxy_pass https://api-interna.example.com/;
        proxy_http_version 1.1;

        proxy_set_header Host api-interna.example.com;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Internal-Api-Key example.internal.key.please.change;
    }

    location / {
        proxy_pass http://frontend_ssr;
    }
}

4. Validacion en FastAPI

El backend debe validar una cabecera interna contra una variable de entorno. El navegador nunca conoce ese valor; solo Nginx.

5. Que debe hacer Angular

Angular debe consumir la ruta proxy del dominio publico y eliminar cualquier usuario, contraseña, bearer bootstrap o intercambio tecnico de tokens.

Dicho de otra forma, Angular usa el servicio, pero no forma parte del perimetro de confianza.

6. Como verificar que la configuracion es correcta

La comprobacion mas util es probar las dos rutas: la ruta publica proxy debe funcionar y la ruta directa de la API privada debe devolver 403.

7. Checklist de despliegue

Usar una INTERNAL_API_KEY larga y aleatoria en el entorno del backend.

Configurar Nginx en el dominio publico para inyectar esa misma cabecera.

Mantener el dominio privado de la API sin esa cabecera inyectada.

Apuntar Angular en produccion a la ruta publica proxy, no al host privado de la API.

Verificar que la ruta publica proxy responde 200 y la ruta directa privada responde 403.

Errores habituales

Inyectar el mismo secreto desde Angular o guardarlo en ficheros de entorno que llegan al navegador.

Reutilizar un /api ya ocupado en vez de crear un namespace dedicado como /api/crypto/.

Olvidar los file replacements y enviar URLs localhost a produccion.

Creer que CORS o esconder botones equivale a proteccion backend.

Cuando es recomendable este patron

Usalo cuando la web necesite la API pero no quieras publicar credenciales reutilizables ni permitir el uso directo del endpoint por terceros.

Si la API debe ser publica por definicion, abrirla con buen rate limiting puede ser mas simple. Si los datos dependen del usuario, entonces lo correcto es autenticacion real por usuario.