# 🔐 Instrucciones de Configuración - Laravel Sanctum

## ✅ Implementación Completada

Se ha implementado el sistema de autenticación con tokens Sanctum utilizando **middleware opcional** para mantener retrocompatibilidad.

### Archivos creados/modificados:
- ✅ `app/Http/Middleware/OptionalSanctumAuth.php` - Middleware que acepta requests con o sin token
- ✅ `app/Models/User.php` - Agregado trait `HasApiTokens`
- ✅ `app/Http/Controllers/UserController.php` - Agregados métodos `loginWithToken()` y `logout()`
- ✅ `routes/api.php` - Rutas reorganizadas con middleware opcional
- ✅ `bootstrap/app.php` - Middleware registrado como `auth.optional`

---

## 📋 Pasos de Configuración Pendientes

### 1. Instalar Laravel Sanctum

```bash
composer require laravel/sanctum
```

### 2. Publicar configuración de Sanctum (opcional)

```bash
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
```

### 3. Crear la tabla `personal_access_tokens` en SQL Server

**IMPORTANTE:** Debes crear esta tabla MANUALMENTE en tu base de datos SQL Server para no perder datos existentes.

```sql
USE [nombre_de_tu_base_de_datos];
GO

CREATE TABLE personal_access_tokens (
    id BIGINT IDENTITY(1,1) PRIMARY KEY,
    tokenable_type NVARCHAR(255) NOT NULL,
    tokenable_id BIGINT NOT NULL,
    name NVARCHAR(255) NOT NULL,
    token NVARCHAR(64) NOT NULL UNIQUE,
    abilities NVARCHAR(MAX) NULL,
    last_used_at DATETIME2 NULL,
    expires_at DATETIME2 NULL,
    created_at DATETIME2 NULL,
    updated_at DATETIME2 NULL
);

-- Crear índice para mejorar performance
CREATE INDEX idx_tokenable ON personal_access_tokens (tokenable_type, tokenable_id);
GO
```

**Descripción de campos:**
- `tokenable_type`: Clase del modelo (ej: `App\Models\User`)
- `tokenable_id`: ID del usuario (valor del campo `login` en tu caso)
- `name`: Nombre del dispositivo/app
- `token`: Hash SHA-256 del token (64 caracteres)
- `abilities`: Permisos en formato JSON (opcional)
- `last_used_at`: Última vez que se usó el token
- `created_at/updated_at`: Timestamps

### 4. Verificar conexión en config/database.php

Asegúrate de que tu conexión `sqlsrv_web_productivo` esté configurada correctamente.

---

## 🚀 Uso de la API

### Login SIN Token (versión antigua - retrocompatibilidad)

**Endpoint:** `POST /api/login`

```json
{
  "login": "usuario123",
  "clave": "password123"
}
```

**Respuesta:**
```json
{
  "success": true,
  "message": "Login successful",
  "user": { ... }
}
```

---

### Login CON Token (versión nueva)

**Endpoint:** `POST /api/login_token`

```json
{
  "login": "usuario123",
  "clave": "password123",
  "device_name": "android-samsung-s21"
}
```

**Respuesta:**
```json
{
  "success": true,
  "message": "Login successful",
  "user": { ... },
  "token": "1|abc123xyz456..."
}
```

**Guardar el token en la app móvil** y enviarlo en todas las requests subsiguientes.

---

### Usar el Token en Requests

En todas las requests protegidas, enviar el token en el header:

```
Authorization: Bearer 1|abc123xyz456...
```

---

### Logout

**Endpoint:** `POST /api/logout`

**Headers:**
```
Authorization: Bearer 1|abc123xyz456...
```

**Respuesta:**
```json
{
  "success": true,
  "message": "Logout exitoso"
}
```

---

## 🔒 Comportamiento del Middleware Opcional

### Rutas con `auth.optional`:

1. **CON token válido:** ✅ Usuario autenticado, puedes usar `auth()->user()`
2. **SIN token:** ✅ Request permitida (retrocompatibilidad)
3. **Token inválido/expirado:** ❌ Error 401

### Ejemplo en controlador:

```php
public function guardar_ubicacion_chofer(Request $request) {
    // Detectar si el usuario está autenticado
    $user = auth('sanctum')->user();
    
    if ($user) {
        // Usuario nuevo con token
        $userId = $user->login;
    } else {
        // Usuario viejo sin token - obtener del request
        $userId = $request->input('usuario');
    }
    
    // ... resto del código
}
```

---

## 📱 Plan de Migración

### Fase 1: Implementación (ACTUAL)
- ✅ Backend preparado con middleware opcional
- ✅ Endpoint `/api/login_token` disponible
- ✅ Apps viejas siguen funcionando sin cambios

### Fase 2: Actualización Gradual
- Lanzar nueva versión de la app móvil
- App usa `/api/login_token` y guarda el token
- App envía token en todas las requests
- Apps viejas siguen funcionando

### Fase 3: Migración Completa (cuando todos actualicen)
- Cambiar `auth.optional` por `auth:sanctum` en rutas
- Deprecar `/api/login` (o dejarlo solo para testing)
- Obligatorio usar tokens

---

## 🧪 Testing

### Probar con Postman/Insomnia:

**1. Login con token:**
```
POST http://localhost/api/login_token
Body: { "login": "...", "clave": "..." }
```

**2. Copiar el token de la respuesta**

**3. Usar el token en otra request:**
```
POST http://localhost/api/guardar_ubicacion_chofer
Headers: Authorization: Bearer [TOKEN_AQUÍ]
Body: { ... }
```

---

## ⚠️ Notas Importantes

1. **Los tokens NO expiran por defecto** - puedes configurar expiración en `config/sanctum.php`
2. **Un usuario puede tener múltiples tokens** (uno por dispositivo)
3. **El logout solo revoca el token actual**, no todos los tokens del usuario
4. **Para revocar todos los tokens:** `$user->tokens()->delete()`

---

## 🔧 Troubleshooting

### Error: "Class 'Laravel\Sanctum\HasApiTokens' not found"
→ Ejecutar: `composer require laravel/sanctum`

### Error: "Table 'personal_access_tokens' doesn't exist"
→ Crear la tabla manualmente con el SQL proporcionado arriba

### Token no funciona
→ Verificar que el header sea: `Authorization: Bearer TOKEN`
→ Verificar que el token esté completo (incluir el número y el pipe: `1|abc123...`)

---

## 📞 Soporte

Si tienes problemas, revisa:
1. Logs de Laravel: `storage/logs/laravel.log`
2. Verificar que Sanctum esté instalado: `composer show laravel/sanctum`
3. Verificar que la tabla exista en la base de datos
