> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Módulo Auth

> Autenticación de usuario, registro y gestión de sesión mediante base44.auth.

<Warning>
  Esta página es parte de una habilidad de agente de codificación con IA y está escrita para agentes, no para humanos. Para la documentación de Base44 legible por humanos, consulta la [documentación para desarrolladores](/developers).
</Warning>

# Módulo Auth

Autenticación de usuario, registro y gestión de sesión mediante `base44.auth`.

## Contenido

* [Tipos TypeScript](#typescript-types)
* [Métodos](#methods)
* [Ejemplos](#examples)
* [Manejo de errores](#error-handling)
* [Proveedores de autenticación](#auth-providers)
* [Disponibilidad de entorno](#environment-availability)
* [Visibilidad de la app](#app-visibility)
* [Limitaciones](#limitations)

***

## Tipos TypeScript

### Interfaz User

```typescript theme={null}
interface User {
  id: string;
  created_date: string;
  updated_date: string;
  email: string;
  full_name: string | null;
  disabled: boolean | null;
  is_verified: boolean;
  app_id: string;
  is_service: boolean;
  role: string;
  [key: string]: any; // Campos de esquema personalizados
}
```

### Interfaz LoginResponse

```typescript theme={null}
interface LoginResponse {
  access_token: string;  // Token JWT
  user: User;           // Objeto de usuario completo
}
```

### Interfaces de parámetros

#### RegisterParams

```typescript theme={null}
interface RegisterParams {
  email: string;                    // Requerido
  password: string;                 // Requerido
  turnstile_token?: string | null;  // Opcional: Cloudflare Turnstile para protección contra bots
  referral_code?: string | null;    // Opcional: código de referencia
}
```

#### VerifyOtpParams

```typescript theme={null}
interface VerifyOtpParams {
  email: string;     // Correo del usuario
  otpCode: string;   // Código OTP del correo
}
```

#### ResetPasswordParams

```typescript theme={null}
interface ResetPasswordParams {
  resetToken: string;   // Token del correo de restablecimiento de contraseña
  newPassword: string;  // Nueva contraseña a establecer
}
```

#### ChangePasswordParams

```typescript theme={null}
interface ChangePasswordParams {
  userId: string;          // ID de usuario
  currentPassword: string; // Contraseña actual para verificación
  newPassword: string;     // Nueva contraseña a establecer
}
```

### Tipo Provider

```typescript theme={null}
type Provider = 'google' | 'microsoft' | 'facebook';
```

***

## Métodos

### Interfaz del módulo

```typescript theme={null}
interface AuthModule {
  // Información del usuario
  me(): Promise<User>;
  updateMe(data: Partial<Omit<User, 'id' | 'created_date' | 'updated_date' | 'app_id' | 'is_service'>>): Promise<User>;
  isAuthenticated(): Promise<boolean>;

  // Login/Logout
  loginViaEmailPassword(email: string, password: string, turnstileToken?: string): Promise<LoginResponse>;
  loginWithProvider(provider: Provider, fromUrl?: string): void;
  logout(redirectUrl?: string): void;
  redirectToLogin(nextUrl: string): void;

  // Gestión de tokens
  setToken(token: string, saveToStorage?: boolean): void;

  // Registro
  register(params: RegisterParams): Promise<any>;
  verifyOtp(params: VerifyOtpParams): Promise<any>;
  resendOtp(email: string): Promise<any>;

  // Gestión de usuarios
  inviteUser(userEmail: string, role: string): Promise<any>;

  // Gestión de contraseñas
  resetPasswordRequest(email: string): Promise<any>;
  resetPassword(params: ResetPasswordParams): Promise<any>;
  changePassword(params: ChangePasswordParams): Promise<any>;
}
```

### Tabla de referencia de métodos

| Método                    | Parámetros                                                 | Tipo de retorno          | Descripción                                                                                                                                      |
| ------------------------- | ---------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `register()`              | `params: RegisterParams`                                   | `Promise<any>`           | Crea una nueva cuenta de usuario                                                                                                                 |
| `loginViaEmailPassword()` | `email: string, password: string, turnstileToken?: string` | `Promise<LoginResponse>` | Autentica con correo/contraseña                                                                                                                  |
| `loginWithProvider()`     | `provider: Provider, fromUrl?: string`                     | `void`                   | Inicia el flujo de inicio de sesión OAuth. Proveedores: `'google'` (por defecto), `'microsoft'`, `'facebook'` (habilita en configuración de app) |
| `me()`                    | Ninguno                                                    | `Promise<User>`          | Obtiene el usuario autenticado actual                                                                                                            |
| `updateMe()`              | `data: Partial<User>`                                      | `Promise<User>`          | Actualiza el perfil del usuario actual                                                                                                           |
| `logout()`                | `redirectUrl?: string`                                     | `void`                   | Redirige al logout del lado del servidor (borra cookies HTTP-only y sesión), luego a redirectUrl o URL actual                                    |
| `redirectToLogin()`       | `nextUrl: string`                                          | `void`                   | ⚠️ **Evitar** - Prefiere UI de login personalizada con `loginViaEmailPassword()` o `loginWithProvider()`                                         |
| `isAuthenticated()`       | Ninguno                                                    | `Promise<boolean>`       | Comprueba si el usuario ha iniciado sesión                                                                                                       |
| `setToken()`              | `token: string, saveToStorage?: boolean`                   | `void`                   | Establece manualmente el token de autenticación                                                                                                  |
| `inviteUser()`            | `userEmail: string, role: string`                          | `Promise<any>`           | Envía correo de invitación                                                                                                                       |
| `verifyOtp()`             | `params: VerifyOtpParams`                                  | `Promise<any>`           | Verifica código OTP                                                                                                                              |
| `resendOtp()`             | `email: string`                                            | `Promise<any>`           | Reenvía código OTP                                                                                                                               |
| `resetPasswordRequest()`  | `email: string`                                            | `Promise<any>`           | Solicita restablecimiento de contraseña                                                                                                          |
| `resetPassword()`         | `params: ResetPasswordParams`                              | `Promise<any>`           | Restablece contraseña con token                                                                                                                  |
| `changePassword()`        | `params: ChangePasswordParams`                             | `Promise<any>`           | Cambia contraseña de usuario                                                                                                                     |

***

## Ejemplos

### Registrar nuevo usuario (flujo completo)

El registro requiere verificación de correo antes del login. Flujo completo:

1. **Registrar** - Crear la cuenta de usuario
2. **Correo de verificación enviado** - El usuario recibe un código OTP
3. **Verificar OTP** - El usuario introduce el código para verificar el correo
4. **Iniciar sesión** - El usuario ahora puede iniciar sesión

```javascript theme={null}
try {
  // Paso 1: Registrar el usuario
  await base44.auth.register({
    email: "user@example.com",
    password: "securePassword123",
    referral_code: "OPTIONAL_CODE",    // opcional
    turnstile_token: "CAPTCHA_TOKEN"   // opcional, para protección contra bots
  });
  console.log('Registration successful. Check email for OTP code.');

  // Paso 2: El usuario recibe un correo con código OTP (por ejemplo, "123456")

  // Paso 3: Verificar el código OTP
  await base44.auth.verifyOtp({
    email: "user@example.com",
    otpCode: "123456"  // código del correo de verificación
  });
  console.log('Email verified successfully.');

  // Paso 4: Ahora el usuario puede iniciar sesión
  const loginResponse = await base44.auth.loginViaEmailPassword(
    "user@example.com",
    "securePassword123"
  );
  console.log('Login successful:', loginResponse.user);

} catch (error) {
  console.error('Registration flow failed:', error.message);
  // Maneja errores específicos (ver sección Manejo de errores)
}
```

> **Importante**: Los usuarios no pueden iniciar sesión hasta que completen la verificación OTP. Intentar llamar a `loginViaEmailPassword` antes de la verificación fallará.

### Iniciar sesión con correo/contraseña

```javascript theme={null}
try {
  const response = await base44.auth.loginViaEmailPassword(
    "user@example.com",
    "password123",
    turnstileToken  // opcional: para protección contra bots
  );

  console.log('Login successful');
  console.log('User:', response.user);
  console.log('Token:', response.access_token);

  // El JWT se almacena automáticamente para solicitudes posteriores

} catch (error) {
  console.error('Login failed:', error.message);
  if (error.status === 401) {
    console.error('Invalid credentials');
  } else if (error.status === 403) {
    console.error('Email not verified. Please check your email for OTP.');
  }
}
```

### Iniciar sesión con proveedor OAuth

Proveedores admitidos: `'google'` (habilitado por defecto), `'microsoft'` y `'facebook'`. Habilita Microsoft o Facebook en la configuración de autenticación de tu app antes de usarlos.

```javascript theme={null}
// Redirigir a Google OAuth
base44.auth.loginWithProvider('google');

// Redirigir a Google OAuth y volver a la página actual después
base44.auth.loginWithProvider('google', window.location.href);

// Microsoft o Facebook (habilita en configuración de app primero)
base44.auth.loginWithProvider('microsoft');
base44.auth.loginWithProvider('facebook', '/dashboard');
```

### Obtener usuario actual

```javascript theme={null}
try {
  const user = await base44.auth.me();

  if (user) {
    console.log('User ID:', user.id);
    console.log('Email:', user.email);
    console.log('Name:', user.full_name);
    console.log('Role:', user.role);
    console.log('Verified:', user.is_verified);
  } else {
    console.log('User not authenticated');
  }

} catch (error) {
  console.error('Failed to fetch user:', error.message);
  if (error.status === 401) {
    // Token expirado o inválido - navega a tu página de login personalizada
    navigate('/login');
  }
}
```

### Actualizar perfil de usuario

```javascript theme={null}
try {
  const updatedUser = await base44.auth.updateMe({
    full_name: "John Doe",
    // Los campos de esquema personalizados pueden actualizarse aquí
    phone: "+1234567890",
    preferences: { theme: "dark" }
  });

  console.log('Profile updated:', updatedUser);

} catch (error) {
  console.error('Profile update failed:', error.message);
  if (error.status === 400) {
    console.error('Invalid data provided');
  } else if (error.status === 401) {
    console.error('Authentication required');
    navigate('/login');
  }
}
```

### Comprobar estado de autenticación

```javascript theme={null}
try {
  const isLoggedIn = await base44.auth.isAuthenticated();

  if (isLoggedIn) {
    // Mostrar UI autenticada
    console.log('User is authenticated');
  } else {
    // Mostrar botón de login
    console.log('User is not authenticated');
  }

} catch (error) {
  console.error('Failed to check authentication:', error.message);
  // En error, tratar como no autenticado
}
```

### Logout

Logout redirige al usuario al endpoint de logout del lado del servidor (`/api/apps/auth/logout`) para borrar cookies HTTP-only y la sesión, luego redirige a la URL dada (o a la página actual si se omite). Requiere un entorno de navegador.

```javascript theme={null}
// Logout: borra sesión mediante el servidor, luego redirige a la página actual
base44.auth.logout();

// Logout y redirigir a página de despedida después
base44.auth.logout("/goodbye");

// Logout y redirigir a página de inicio
base44.auth.logout("/");
```

### Patrón de ruta protegida

```javascript theme={null}
// Usando una función de navegación (por ejemplo, useNavigate de React Router, router de Next.js)
async function requireAuth(navigate) {
  try {
    const user = await base44.auth.me();

    if (!user) {
      // Navega a tu página de login personalizada
      navigate('/login', { state: { returnTo: window.location.pathname } });
      return null;
    }

    return user;

  } catch (error) {
    console.error('Authentication check failed:', error.message);
    navigate('/login', { state: { returnTo: window.location.pathname } });
    return null;
  }
}

// Uso en tu app
async function loadProtectedPage(navigate) {
  const user = await requireAuth(navigate);
  if (!user) {
    // Navegará al login
    return;
  }

  // Continúa con lógica autenticada
  console.log('Welcome,', user.full_name);
}
```

### Establecer token de autenticación

```javascript theme={null}
// ADVERTENCIA DE SEGURIDAD: Nunca codifiques tokens ni los expongas en código cliente
// Los tokens solo deben recibirse de flujos de autenticación seguros

// Establecer token y guardar en localStorage (por defecto)
base44.auth.setToken(receivedToken);

// Establecer token sin guardar en localStorage (sesión temporal)
base44.auth.setToken(receivedToken, false);

// Verificar que el token se estableció
try {
  const isAuthenticated = await base44.auth.isAuthenticated();
  if (!isAuthenticated) {
    console.error('Token validation failed');
  }
} catch (error) {
  console.error('Failed to set token:', error.message);
}
```

### Invitar usuario a la aplicación

```javascript theme={null}
try {
  // Nota: Normalmente requiere privilegios de administrador
  const response = await base44.auth.inviteUser(
    "newuser@example.com",
    "user"  // o "admin"
  );

  console.log('Invitation sent successfully');

} catch (error) {
  console.error('Failed to invite user:', error.message);
  if (error.status === 403) {
    console.error('Insufficient permissions to invite users');
  } else if (error.status === 400) {
    console.error('Invalid email or role');
  }
}
```

### Verificación OTP

```javascript theme={null}
try {
  // Verificar código OTP enviado al correo del usuario
  await base44.auth.verifyOtp({
    email: "user@example.com",
    otpCode: "123456"
  });

  console.log('OTP verified successfully');

} catch (error) {
  console.error('OTP verification failed:', error.message);
  if (error.status === 400) {
    console.error('Invalid or expired OTP code');
  } else if (error.status === 429) {
    console.error('Too many attempts. Please try again later.');
  }
}

// Reenviar OTP si es necesario
try {
  await base44.auth.resendOtp("user@example.com");
  console.log('OTP resent successfully');

} catch (error) {
  console.error('Failed to resend OTP:', error.message);
  if (error.status === 429) {
    console.error('Too many requests. Please wait before trying again.');
  }
}
```

### Flujo de restablecimiento de contraseña

```javascript theme={null}
// Paso 1: Solicitar restablecimiento de contraseña
try {
  await base44.auth.resetPasswordRequest("user@example.com");
  console.log('Password reset email sent. Check your inbox.');

} catch (error) {
  console.error('Password reset request failed:', error.message);
  if (error.status === 429) {
    console.error('Too many requests. Please try again later.');
  }
  // Nota: Por seguridad, no reveles si el correo existe
}

// Paso 2: Restablecer contraseña con token del correo
try {
  await base44.auth.resetPassword({
    resetToken: "token-from-email",
    newPassword: "newSecurePassword123"
  });

  console.log('Password reset successfully. You can now log in.');

} catch (error) {
  console.error('Password reset failed:', error.message);
  if (error.status === 400) {
    console.error('Invalid or expired reset token');
  } else if (error.status === 422) {
    console.error('Password does not meet requirements');
  }
}
```

### Cambiar contraseña

```javascript theme={null}
try {
  const currentUser = await base44.auth.me();

  if (!currentUser) {
    throw new Error('User must be authenticated to change password');
  }

  await base44.auth.changePassword({
    userId: currentUser.id,
    currentPassword: "oldPassword123",
    newPassword: "newSecurePassword456"
  });

  console.log('Password changed successfully');

} catch (error) {
  console.error('Password change failed:', error.message);
  if (error.status === 401) {
    console.error('Current password is incorrect');
  } else if (error.status === 422) {
    console.error('New password does not meet requirements');
  } else if (error.status === 403) {
    console.error('Not authorized to change this password');
  }
}
```

***

## Manejo de errores

### Escenarios de error comunes

El módulo auth puede lanzar varios errores. Aquí hay escenarios comunes y cómo manejarlos:

#### Errores de autenticación (401/403)

```javascript theme={null}
try {
  const user = await base44.auth.me();
} catch (error) {
  if (error.status === 401) {
    // Token expirado o inválido - navega a tu página de login personalizada
    navigate('/login');
  } else if (error.status === 403) {
    // Correo no verificado o permisos insuficientes
    console.error('Access denied:', error.message);
  }
}
```

#### Errores de validación (400/422)

```javascript theme={null}
try {
  await base44.auth.register({
    email: "invalid-email",
    password: "weak"
  });
} catch (error) {
  if (error.status === 400) {
    console.error('Invalid input:', error.message);
    // Maneja errores de validación
  } else if (error.status === 422) {
    console.error('Data validation failed:', error.details);
  }
}
```

#### Limitación de tasa (429)

```javascript theme={null}
try {
  await base44.auth.resendOtp("user@example.com");
} catch (error) {
  if (error.status === 429) {
    console.error('Too many requests. Please wait before trying again.');
    // Muestra cuenta regresiva o deshabilita el botón temporalmente
  }
}
```

#### Manejador de errores genérico

```javascript theme={null}
function handleAuthError(error) {
  switch (error.status) {
    case 400:
      return 'Invalid input. Please check your data.';
    case 401:
      return 'Authentication required. Redirecting to login...';
    case 403:
      return 'Access denied. You may need to verify your email.';
    case 404:
      return 'Resource not found.';
    case 422:
      return 'Validation failed. Please check your input.';
    case 429:
      return 'Too many requests. Please try again later.';
    case 500:
      return 'Server error. Please try again.';
    default:
      return 'An unexpected error occurred.';
  }
}

// Uso
try {
  await base44.auth.loginViaEmailPassword(email, password);
} catch (error) {
  console.error(handleAuthError(error));
}
```

***

## Proveedores de autenticación

Configura los proveedores de autenticación en el panel de tu app:

### Proveedores disponibles

**Integrados (todos los planes):**

* **Email/Password** - Predeterminado, siempre habilitado
* **Google** - Autenticación OAuth
* **Microsoft** - Autenticación OAuth
* **Facebook** - Autenticación OAuth

**Proveedores SSO (plan Elite):**

* **Okta**
* **Azure AD**
* **GitHub**

### Usar proveedores OAuth

* **Google** – habilitado por defecto.
* **Microsoft** – habilita en la configuración de autenticación de tu app antes de usarlo.
* **Facebook** – habilita en la configuración de autenticación de tu app antes de usarlo.

```javascript theme={null}
// Iniciar el flujo de inicio de sesión OAuth
base44.auth.loginWithProvider('google');

// Volver a una página específica tras la autenticación
base44.auth.loginWithProvider('microsoft', '/dashboard');

// Valores admitidos: 'google', 'microsoft', 'facebook'
```

***

## Disponibilidad de entorno

| Entorno                  | Disponibilidad | Notas                                                                               |
| ------------------------ | -------------- | ----------------------------------------------------------------------------------- |
| **Frontend**             | ✅ Sí           | Todos los métodos disponibles                                                       |
| **Funciones de backend** | ✅ Sí           | Usa `createClientFromRequest(req)` para cliente autenticado                         |
| **Rol de servicio**      | ❌ No           | Los métodos de autenticación no están disponibles en el contexto de rol de servicio |

### Uso en frontend

```javascript theme={null}
// Uso estándar en navegador
const user = await base44.auth.me();
```

### Uso en funciones de backend

```javascript theme={null}
import { createClientFromRequest } from "@base44/sdk";

Deno.serve(async (req) => {
  const base44 = createClientFromRequest(req);

  // Obtiene el usuario del contexto de la solicitud
  const user = await base44.auth.me();

  // Operaciones de usuario aquí...
  return Response.json({ user });
});
```

***

## Visibilidad de la app

Controla quién puede acceder a tu app en la configuración de la app:

### Apps públicas

* No se requiere login para acceso básico
* Los usuarios pueden ver contenido público sin autenticación
* Los usuarios autenticados obtienen funciones/datos adicionales

### Apps privadas

* Se requiere login para acceder a cualquier contenido
* Los usuarios no autenticados son redirigidos automáticamente al login
* Todo el contenido está protegido por defecto

***

## Limitaciones

### Opciones de UI de autenticación

* **Recomendado:** Construye una UI de login/registro personalizada usando `loginViaEmailPassword()` y `loginWithProvider()` para control total sobre la experiencia de usuario y la marca
* **Alternativa:** `redirectToLogin()` usa las páginas de autenticación alojadas de Base44 con personalización limitada

### Login alojado (mediante redirectToLogin)

* `redirectToLogin()` muestra las opciones de inicio de sesión y registro en la misma página
* No hay un método `redirectToSignup()` separado
* Los usuarios pueden cambiar entre login/registro en la página alojada
* ⚠️ **Nota:** Prefiere construir una UI de login personalizada para una mejor experiencia de usuario

### Requisitos de contraseña

* Se aplican requisitos mínimos de longitud y complejidad
* Los requisitos no se exponen mediante API
* Se devuelven errores de validación cuando no se cumplen los requisitos

### Limitación de tasa

* Las solicitudes de OTP tienen limitación de tasa para prevenir abusos
* Las solicitudes de restablecimiento de contraseña tienen limitación de tasa
* Los intentos de inicio de sesión pueden tener limitación de tasa con protección Turnstile

### Gestión de tokens

* Los JWT se almacenan automáticamente en localStorage por defecto
* La expiración y renovación de tokens no se exponen en la API
* Llama a `me()` o `isAuthenticated()` para verificar la validez del token

***

## Mejores prácticas

### 1. Siempre maneja errores

```javascript theme={null}
try {
  await base44.auth.loginViaEmailPassword(email, password);
} catch (error) {
  // Siempre maneja errores de autenticación
  console.error('Login failed:', error.message);
}
```

### 2. Verifica la autenticación antes de acciones protegidas

```javascript theme={null}
const user = await requireAuth();
if (!user) return; // Redirigirá al login
// Procede con acción autenticada
```

### 3. Usa seguridad de tipos con TypeScript

```typescript theme={null}
import type { User, LoginResponse } from '@base44/sdk';

const user: User = await base44.auth.me();
const response: LoginResponse = await base44.auth.loginViaEmailPassword(email, password);
```

### 4. No codifiques credenciales

```javascript theme={null}
// ❌ MAL
base44.auth.setToken("hardcoded-token-here");

// ✅ BIEN
const token = await secureAuthFlow();
base44.auth.setToken(token);
```

### 5. Proporciona retroalimentación al usuario

```javascript theme={null}
try {
  await base44.auth.register(params);
  showSuccessMessage('Registration successful! Check your email for verification code.');
} catch (error) {
  showErrorMessage('Registration failed: ' + error.message);
}
```

### 6. Maneja la expiración de tokens con elegancia

```javascript theme={null}
try {
  const user = await base44.auth.me();
} catch (error) {
  if (error.status === 401) {
    // Borra el estado local y navega al login
    localStorage.clear();
    navigate('/login');
  }
}
```

### 7. Construye una UI de login personalizada (recomendado)

```javascript theme={null}
// ✅ RECOMENDADO - Formulario de login personalizado con métodos directos
const handleLogin = async (email, password) => {
  try {
    const { user } = await base44.auth.loginViaEmailPassword(email, password);
    navigate('/dashboard');
  } catch (error) {
    setError(error.message);
  }
};

const handleGoogleLogin = () => {
  base44.auth.loginWithProvider('google', '/dashboard');
};

// ❌ EVITAR - Redirigir a página de login alojada
// base44.auth.redirectToLogin(window.location.href);
```

<Note>Esta página fue traducida usando IA. Para obtener la información más precisa y actualizada, consulta la [versión en inglés](/).</Note>
