From 65dee7382f3f881b93564401636006a1d1da2883 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Mon, 13 Oct 2025 03:11:46 -0600 Subject: [PATCH] Add comprehensive documentation for components, Traefik and Authentik - Document all authentication components architecture - UserAvatar, UserMetadata components - Individual action buttons with their specific functionality - useAuthentik() composable with full API documentation - Explain Authentik Proxy Outpost flow - Forward Auth mechanism - Step-by-step authentication flow - Advantages of proxy-based authentication - Detail Traefik routing configuration - Router 1: Public routes (PWA resources) with priority 100 - Router 2: Protected routes with Authentik middleware - CORS and headers middleware explanation - Add complete Authentik setup guide - Traefik middleware configuration - Authentik Provider and Application setup - Network configuration requirements - Include troubleshooting section - Common errors and solutions - PWA offline functionality - Headers debugging --- README.md | 244 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 220 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 4a36d25..e229428 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,60 @@ Este proyecto incluye hooks de Claude Code para monitorear automáticamente las 📖 Ver documentación completa en [`.claude/hooks/README.md`](.claude/hooks/README.md) +## Arquitectura de Componentes + +### Componentes de Autenticación + +La aplicación utiliza componentes Vue modulares para manejar la autenticación: + +#### 1. **UserAvatar** (`app/components/auth/UserAvatar.vue`) +- Muestra el avatar del usuario (generado por UI Avatars) +- Información básica: nombre/username, email y UID +- Se renderiza solo cuando el usuario está autenticado + +#### 2. **UserMetadata** (`app/components/auth/UserMetadata.vue`) +- Card detallada con todos los metadatos del usuario +- Muestra: username, email, nombre completo, UID y grupos +- Incluye badges para visualizar los grupos del usuario + +#### 3. **Botones de Acción** (componentes individuales) +Cada botón es un componente independiente con su propia lógica: + +- **SessionStatusButton**: Verifica el estado de la sesión contra Authentik + - Hace una petición a `/api/auth/status` + - Muestra notificaciones toast con el resultado + - Maneja casos offline y errores de conexión + +- **ProfileButton**: Redirige al perfil de usuario en Authentik + - Abre el panel de usuario de Authentik en nueva pestaña + - URL: `{authentikUrl}/if/user/` + +- **LogoutButton**: Cierra sesión en Authentik + - Invalida la sesión en todas las aplicaciones + - Redirige a: `{authentikUrl}/flows/-/default/invalidation/` + +- **LoginButton**: Fuerza re-autenticación + - Recarga la página para activar el flujo de login de Authentik + +### Composable `useAuthentik()` + +Composable centralizado para manejar autenticación (`app/composables/useAuthentik.ts`): + +**Funcionalidades:** +- Lee headers de Authentik en el servidor (SSR) +- Almacena información del usuario en `useState` (compartido entre cliente/servidor) +- Proporciona funciones reactivas: `user`, `isAuthenticated` +- Métodos: `logout()`, `goToProfile()`, `checkSessionStatus()` + +**Headers leídos del Proxy:** +```typescript +X-authentik-username // Nombre de usuario +X-authentik-email // Email +X-authentik-name // Nombre completo +X-authentik-groups // Grupos (separados por |) +X-authentik-uid // ID único del usuario +``` + ## Despliegue El proyecto incluye Gitea Actions que automáticamente: @@ -79,39 +133,181 @@ Para configurar el despliegue automático, ve a tu repositorio en Gitea: 📄 Ver ejemplo completo en [`.env.example`](.env.example) -### Configuración de Authentik Proxy Outpost +## Configuración de Traefik y Authentik -Esta plantilla requiere un **Authentik Proxy Outpost** ya configurado en Traefik. +### 🔐 Cómo Funciona Authentik Proxy Outpost + +Authentik Proxy Outpost actúa como un **Forward Auth** middleware que intercepta todas las peticiones antes de que lleguen a tu aplicación: + +``` +Usuario → Traefik → Authentik Forward Auth → Aplicación Nuxt + ↓ (si no auth) + Redirect a Login +``` + +**Flujo de autenticación:** + +1. **Usuario hace petición** → Traefik recibe la petición a tu dominio +2. **Traefik consulta Authentik** → Envía la petición al middleware de Forward Auth +3. **Authentik valida sesión:** + - ✅ **Con sesión válida**: Authentik agrega headers con info del usuario y envía la petición a tu app + - ❌ **Sin sesión**: Authentik redirige al usuario al flujo de login +4. **Tu app recibe la petición** → Con headers de usuario ya inyectados (SSR) + +**Ventajas:** +- ✅ No necesitas implementar OAuth en tu app +- ✅ La autenticación se maneja completamente fuera de tu código +- ✅ Los headers llegan automáticamente en cada petición SSR +- ✅ Funciona con cualquier framework (Nuxt, Next.js, PHP, etc.) + +### 🚦 Configuración de Reglas de Traefik + +El `docker-compose.yml` configura **dos routers** en Traefik para balancear seguridad y funcionalidad PWA: + +#### Router 1: Rutas Públicas (Sin Autenticación) - Prioridad 100 + +```yaml +# Rutas que NO requieren autenticación +- PathPrefix(`/manifest.webmanifest`) # Manifest PWA +- PathPrefix(`/sw.js`) # Service Worker +- PathPrefix(`/workbox-`) # Workbox (PWA) +- PathPrefix(`/icon-`) # Iconos de la app +- PathPrefix(`/apple-touch-icon`) # Icono iOS +- PathPrefix(`/favicon.ico`) # Favicon +- PathPrefix(`/robots.txt`) # SEO +- PathPrefix(`/offline.html`) # Página offline PWA +- PathPrefix(`/api/_nuxt_icon/`) # API de iconos de Nuxt +``` + +**Middlewares aplicados:** +- `${APP_NAME}-headers`: Headers personalizados (X-Forwarded-Proto) +- `${APP_NAME}-cors`: Configuración CORS para recursos públicos + +**¿Por qué sin autenticación?** +- Los Service Workers necesitan acceso sin auth para funcionar offline +- Los manifests PWA deben ser públicos para instalación +- Prioridad 100 asegura que estas rutas se evalúen primero + +#### Router 2: Aplicación Protegida (Con Autenticación) - Prioridad 10 + +```yaml +# Todas las demás rutas (Host match) +Host(`${APP_DOMAIN}`) +``` + +**Middlewares aplicados:** +- `authentik-forward-auth@file`: Forward Auth de Authentik +- `${APP_NAME}-headers`: Headers personalizados + +**Características:** +- Prioridad menor (10) → se evalúa después de las rutas públicas +- Cualquier ruta no pública pasa por autenticación +- Authentik inyecta headers con información del usuario + +### 📋 Configuración de Authentik Proxy Outpost **Requisitos previos:** -- Red `traefik-network` creada y Traefik corriendo en ella -- Authentik Forward Auth middleware configurado en Traefik (ej: en `dynamic/middlewares.yml`) -- Proxy Provider de tipo Forward Auth en Authentik +- Traefik corriendo con las redes `traefik-network` y `principal` +- Authentik instalado y funcionando -**Pasos:** +**Pasos de configuración:** -1. **En Authentik:** - - Crea una aplicación para tu dominio - - Crea/usa un Proxy Provider de tipo **Forward auth (single application)** - - Asocia la aplicación al Outpost +#### 1. Crear el Middleware en Traefik -2. **Redes requeridas:** - - `principal` - Red de tu infraestructura - - `traefik-network` - Red donde corre Traefik +Crea o edita el archivo de configuración dinámica de Traefik (ej: `dynamic/middlewares.yml`): -3. **Middleware en Traefik:** - - El `docker-compose.yml` usa `authentik-forward-auth@file` - - Verifica que este middleware esté definido en tu configuración de Traefik - - Si tu middleware tiene otro nombre, actualiza el `docker-compose.yml` +```yaml +http: + middlewares: + authentik-forward-auth: + forwardAuth: + address: http://authentik-server:9000/outpost.goauthentik.io/auth/traefik + trustForwardHeader: true + authResponseHeaders: + - X-authentik-username + - X-authentik-groups + - X-authentik-email + - X-authentik-name + - X-authentik-uid +``` -4. **Headers disponibles en la app:** - - `X-authentik-username`: nombre de usuario - - `X-authentik-email`: email del usuario - - `X-authentik-name`: nombre completo - - `X-authentik-groups`: grupos (separados por `|`) - - `X-authentik-uid`: ID único +**Importante:** Cambia `authentik-server` por el nombre de tu contenedor/servicio de Authentik. -Tu aplicación Nuxt puede leer estos headers para obtener información del usuario autenticado. +#### 2. Configurar Authentik + +**a) Crear un Proxy Provider:** +- Ve a **Admin > Applications > Providers** +- Click en **Create** +- Tipo: **Proxy Provider** +- Configuración: + - **Name**: `Mi App - Forward Auth` + - **Authorization flow**: Selecciona tu flujo (ej: `default-provider-authorization-implicit-consent`) + - **Type**: `Forward auth (single application)` + - **External host**: `https://miapp.ejemplo.com` (tu dominio) + +**b) Crear una Application:** +- Ve a **Admin > Applications > Applications** +- Click en **Create** +- Configuración: + - **Name**: `Mi App` + - **Slug**: `mi-app` + - **Provider**: Selecciona el provider creado arriba + +**c) Vincular al Outpost:** +- Ve a **Admin > Outposts > Outposts** +- Edita tu Outpost (o crea uno nuevo si no existe) +- En **Applications**: Agrega la aplicación creada + +#### 3. Configurar las Redes en Docker Compose + +Tu aplicación necesita estar en ambas redes: + +```yaml +networks: + principal: # Red de tu infraestructura + external: true + traefik-network: # Red donde corre Traefik + external: true +``` + +Asegúrate de que estas redes existan: + +```bash +docker network create principal +docker network create traefik-network +``` + +### 🔍 Headers Disponibles en tu Aplicación + +Una vez configurado, Authentik inyecta estos headers en cada petición: + +| Header | Descripción | Ejemplo | +|--------|-------------|---------| +| `X-authentik-username` | Nombre de usuario | `nucleo000` | +| `X-authentik-email` | Email del usuario | `user@example.com` | +| `X-authentik-name` | Nombre completo | `John Doe` | +| `X-authentik-groups` | Grupos (separados por `\|`) | `admins\|users` | +| `X-authentik-uid` | ID único del usuario | `703cae063c59...` | + +**En Nuxt**, estos headers se leen automáticamente en SSR mediante `useRequestHeaders()`. + +### 🐛 Troubleshooting + +**Problema: "Cannot find name 'process'"** +- ✅ Usa `import.meta.server` en lugar de `process.server` (Nuxt 4) + +**Problema: Redirect loop infinito** +- Verifica que el middleware `authentik-forward-auth@file` esté correctamente configurado +- Revisa que la aplicación esté asociada al Outpost en Authentik +- Comprueba que el External host coincida con tu dominio + +**Problema: Headers no llegan a la aplicación** +- Verifica que `authResponseHeaders` incluya todos los headers necesarios +- Asegúrate de que estés leyendo headers en SSR (`import.meta.server`) + +**Problema: PWA no funciona offline** +- Verifica que las rutas públicas tengan prioridad 100 +- Confirma que `/sw.js`, `/manifest.webmanifest` y `/offline.html` estén en el router público ## Licencia