# Sistema SSO (Single Sign-On) entre Dominios

## Descripción General

Se ha implementado un sistema de autenticación SSO que permite a los usuarios del dominio principal autenticarse automáticamente en el subdominio de comunidades sin compartir sesión entre dominios.

## Flujo de Funcionamiento

### 1. En el Dominio Principal (educaauge.com)

Cuando un usuario logueado accede al enlace de "Comunidad":

```
┌─────────────────────────────────────────────────────┐
│ asside.blade.php                                    │
│                                                     │
│ 1. Verifica si el usuario está logueado             │
│ 2. Obtiene su correo                                │
│ 3. Llama a SSOService::generarURLSSO()             │
│ 4. Genera un token encriptado con:                 │
│    - Email del usuario                             │
│    - Timestamp                                      │
│    - Fecha de expiración (2 horas)                 │
│ 5. Envía la URL con el token como parámetro       │
│                                                     │
│ URL generada:                                      │
│ https://comunidad.educaauge.com/sso-login?        │
│   sso_token=[TOKEN_ENCRIPTADO_BASE64]             │
└─────────────────────────────────────────────────────┘
```

### 2. En el Subdominio de Comunidades (comunidad.educaauge.com)

Cuando el usuario accede a la URL con el token:

```
┌──────────────────────────────────────────────────────────┐
│ routes/web.php → /sso-login                             │
│                                                          │
│ Ruta que llama a:                                       │
│ ComunidadController::procesarSSOLogin()                │
└──────────────────────────────────────────────────────────┘
                          ↓
┌──────────────────────────────────────────────────────────┐
│ ComunidadController::procesarSSOLogin()                 │
│                                                          │
│ 1. Obtiene el token del parámetro ?sso_token=...      │
│ 2. Llama a SSOService::desencriptarTokenSSO()         │
│ 3. Valida:                                             │
│    - Que el token sea válido                          │
│    - Que no esté expirado                             │
│ 4. Extrae el email del payload desencriptado         │
│ 5. Busca al usuario en la BD por email               │
│ 6. Crea la sesión del usuario                        │
│ 7. Crea/actualiza el registro de MiembroComunidad   │
│ 8. Redirige a la comunidad                           │
└──────────────────────────────────────────────────────────┘
```

## Archivos Modificados/Creados

### 1. **app/Services/SSOService.php** (NUEVO)
Servicio que maneja la encriptación y desencriptación de tokens.

**Métodos disponibles:**

- `generarTokenSSO($email)`: Genera un token encriptado
- `desencriptarTokenSSO($token)`: Desencripta y valida el token
- `generarURLSSO($email, $urlDestino)`: Genera la URL completa con el token

### 2. **app/Http/Controllers/ComunidadController.php** (MODIFICADO)

Se agregó:
- Import del `SSOService`
- Método `procesarSSOLogin(Request $request)`: Procesa la autenticación SSO

### 3. **resources/views/aulavirtual/partials/asside.blade.php** (MODIFICADO)

El enlace de comunidades ahora:
- Verifica si el usuario está logueado
- Genera una URL con token SSO
- Si no está logueado, redirige al login de comunidades

### 4. **routes/web.php** (MODIFICADO)

Se agregó la ruta:
```php
Route::get('/sso-login', [ComunidadController::class, 'procesarSSOLogin'])->name('sso.login');
```

### 5. **config/app.php** (MODIFICADO)

Se agregó la configuración:
```php
'comunidad_subdomain_url' => env('COMUNIDAD_SUBDOMAIN_URL', 'https://comunidad.educaauge.com'),
```

## Configuración Necesaria

### En el archivo `.env` (dominio principal):

```env
COMUNIDAD_SUBDOMAIN_URL=https://comunidad.educaauge.com
APP_KEY=base64:... # (Ya debe estar configurada)
```

### En el subdominio de comunidades:

El mismo `APP_KEY` debe estar configurado en ambos dominios para que la encriptación/desencriptación funcione correctamente.

```env
APP_KEY=base64:... # (DEBE SER EL MISMO del dominio principal)
```

## Seguridad

1. **Encriptación AES-256-CBC**: Los tokens están encriptados con la misma clave que Laravel usa para otras encriptaciones.

2. **Token con Expiración**: Los tokens expiran después de 2 horas, evitando que tokens antiguos se usen para acceso no autorizado.

3. **Base64 Encoding**: Los tokens se envían en base64 para que sean seguros en URLs.

4. **Validación en Servidor**: El token se valida completamente en el servidor antes de crear la sesión.

5. **Sin Compartir Sesión**: Cada dominio mantiene su propia sesión independiente, evitando problemas de CORS y seguridad entre dominios.

## Ejemplo de Uso

### Desde la vista blade:

```blade
@php
    $usuarioLoguedo = session('suscrito')['user'] ?? null;
    $urlComunidad = config('app.comunidad_subdomain_url');
    
    if ($usuarioLoguedo) {
        $urlSSO = App\Services\SSOService::generarURLSSO(
            $usuarioLoguedo->email,
            $urlComunidad . '/sso-login'
        );
    } else {
        $urlSSO = $urlComunidad;
    }
@endphp

<a href="{{ $urlSSO }}">Ir a Comunidad</a>
```

### Desde un controlador:

```php
use App\Services\SSOService;

$email = 'usuario@example.com';
$urlComunidad = config('app.comunidad_subdomain_url');
$urlSSO = SSOService::generarURLSSO($email, $urlComunidad . '/sso-login');

return redirect($urlSSO);
```

## Resolución de Problemas

### Token no válido o expirado
- Verifica que `APP_KEY` sea el mismo en ambos dominios
- Revisa los logs en `storage/logs/laravel.log`

### Usuario no encontrado
- Asegúrate de que el email existe en la BD del subdominio de comunidades
- Verifica que el email sea exacto (case-sensitive)

### Sesión no se mantiene
- Revisa que la ruta `/sso-login` esté configurada correctamente
- Asegúrate de que `ComunidadController::procesarSSOLogin()` existe

## Próximos Pasos (Opcional)

Si necesitas:
1. **Sincronizar usuarios** entre dominios automáticamente
2. **Implementar logout SSO** (logout en ambos dominios)
3. **Refresh de token** (actualizar token sin re-autenticar)
4. **Roles y permisos SSO**

Contacta para implementar estas características adicionales.
