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

# Guía rápida de JavaScript

> Conecta tu aplicación de Didit Authentication al inicio de sesión alojado con PKCE, validación de callback, control de sesión y cierre de sesión.

> [!WARNING]
>
> Authentication es una función nueva: usa este ejemplo de flujo alojado con una aplicación que tenga Authentication activado. El paquete `@didit-protocol/auth` aún no está publicado; la API del paquete que se muestra más abajo es una vista previa, no una guía de inicio rápido que puedas instalar.

## Configura el inicio de sesión alojado

Registra la URL de callback exacta y tu origen web para tu aplicación de sandbox. Copia su origen de inicio de sesión (`https://<slug>.sandbox.auth.didit.me`) desde la consola, como se describe en la [visión general](https://docs.didit.me/es/authentication/overview.md). Este ejemplo usa las API de criptografía del navegador y requiere HTTPS, o localhost en sandbox: consulta [desarrollo local](https://docs.didit.me/es/authentication/overview.md#desarrollo-local) para saber qué registrar.

La aplicación gestiona `state` y el verificador PKCE. El inicio de sesión alojado gestiona las pantallas de contraseña, correo electrónico, passkey, teléfono, SSO y MFA obligatoria. Ninguna clave de API debe estar en este código.

```javascript auth.js theme={null}
// Replace both values with your registered application configuration.
const AUTH_BASE = "https://YOUR_SLUG.sandbox.auth.didit.me/";
const REDIRECT_URI = "https://YOUR_APP_ORIGIN/auth/callback";
const PENDING = "didit.auth.pending";
let tokens = null;

function base64url(bytes) {
  return btoa(String.fromCharCode(...bytes))
    .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}

export async function signIn() {
  const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
  const state = base64url(crypto.getRandomValues(new Uint8Array(32)));
  const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
  sessionStorage.setItem(PENDING, JSON.stringify({ verifier, state, startedAt: Date.now() }));
  const url = new URL("sign-in", AUTH_BASE);
  url.search = new URLSearchParams({
    redirect_uri: REDIRECT_URI,
    state,
    code_challenge: base64url(new Uint8Array(digest)),
    code_challenge_method: "S256",
  }).toString();
  window.location.assign(url.href);
}

export async function handleCallback() {
  const query = new URLSearchParams(window.location.search);
  const saved = sessionStorage.getItem(PENDING);
  sessionStorage.removeItem(PENDING);
  history.replaceState(null, "", window.location.pathname);
  if (!saved) throw new Error("Start sign-in again.");
  const pending = JSON.parse(saved);
  if (query.get("state") !== pending.state || Date.now() - pending.startedAt > 600000) {
    throw new Error("Invalid or expired sign-in. Start again.");
  }
  if (query.has("error") || !query.get("code")) throw new Error("Sign-in was not completed.");
  const response = await fetch(new URL("token/", AUTH_BASE), {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "authorization_code",
      code: query.get("code"),
      code_verifier: pending.verifier,
      redirect_uri: REDIRECT_URI,
    }),
  });
  if (!response.ok) throw new Error("Code exchange failed. Start sign-in again.");
  tokens = await response.json();
  return getSession();
}

export async function getSession() {
  if (!tokens) return null;
  const response = await fetch(new URL("session/", AUTH_BASE), {
    headers: { Authorization: `Bearer ${tokens.access_token}` },
    cache: "no-store",
  });
  if (!response.ok) {
    tokens = null;
    throw new Error("Session check failed. Sign in again.");
  }
  return response.json();
}

export async function signOut() {
  const current = tokens;
  tokens = null;
  if (!current) return;
  const response = await fetch(new URL("session/", AUTH_BASE), {
    method: "DELETE",
    headers: { Authorization: `Bearer ${current.access_token}` },
  });
  if (response.status !== 204) throw new Error("Local state cleared; server logout failed.");
}
```

Llama a `signIn()` desde tu botón de inicio de sesión. En la página de callback registrada, llama a `handleCallback()` una sola vez, muestra un estado de carga y muestra su error si falla. Usa `getSession()` para obtener el usuario actual y `signOut()` para cerrar la sesión. El callback elimina su código de la barra de direcciones antes de hacer una solicitud.

Este ejemplo mínimo guarda los tokens en memoria y vuelve a iniciar sesión tras recargar la página o cuando caduca el token de acceso. Para sesiones persistentes, usa tu backend y cookies seguras, o implementa una [rotación de refresh tokens](https://docs.didit.me/es/authentication/tokens-and-jwks.md) serializada. Nunca pongas refresh tokens en URL ni en logs. Una comprobación de sesión en el frontend solo controla la presentación; tu backend debe validar a quien llama en cada solicitud protegida.

## Vista previa de la versión del SDK de autenticación

El núcleo previsto de `@didit-protocol/auth` expone `createDiditAuth({publishableKey})`, `signIn()`, `handleRedirectCallback()`, `getSession()`, `getToken()`, `onAuthStateChange` y `signOut()`, con `vendorData` en la identidad. Está previsto que añada señales de dispositivo automáticas y un punto de entrada de servidor con `verifyToken()`.

La clave publicable es `pk_live_` (aplicación de producción) o `pk_test_` (aplicación de sandbox) seguida de la codificación base64url, sin relleno, del origen de tu aplicación.
El SDK envía sus llamadas a la API a ese origen.
La clave es pública: identifica la aplicación y no es un secreto.

### Step-up y reautenticación en la vista previa

* `stepUp({ action, amount?, currency?, redirectUri? })` invoca el endpoint `POST step-up/` de tu aplicación para preguntar si `action` necesita una comprobación de identidad.
  `action` es `payout`, `bank` o `contact`, y un pago necesita `amount`.
  Cuando se aplica una de tus reglas de step-up, navega a la página de verificación que devuelve Didit.
* `handleStepUpCallback(url?)` se ejecuta en la página a la que vuelve la persona.
  Lee `?step_up=<id>`, lo elimina de la barra de direcciones y lee el resultado con `GET step-up/{id}/`.
* `reauthenticate({ method? })` vuelve a iniciar la sesión de la misma persona, en la página alojada (`method: "redirect"`, el valor predeterminado) o con una passkey (`method: "passkey"`, solo en el dominio de inicio de sesión de Didit de tu aplicación).
  Después de la página alojada, complétalo con `handleRedirectCallback()`.
  Si lo completa otra persona, se rechaza con `step_up_user_mismatch` y la sesión original se mantiene.

Ambos métodos de step-up se resuelven con `{ id, status, approved, rule, method }`, donde `status` es `not_required`, `pending`, `approved`, `review`, `declined` o `expired`.
`redirectUri` toma por defecto la URL de redirección del cliente y debe coincidir exactamente con una de las URL de redirección registradas de tu aplicación: cuando se requiere una comprobación, Didit rechaza cualquier otra dirección.
Antes de que tu backend procese un step-up, vuelve a leer el step-up con `GET step-up/{id}/` y el token de acceso de la persona, porque un resultado informado por el navegador puede alterarse.

Un inicio de sesión headless también puede devolver `protection_required` cuando las reglas de protección de tu aplicación lo marcan.
La persona lo completa entonces con el código que Didit le envió por correo electrónico (`protection.verify({ code })`) o con una passkey (`protection.passkey()`), y `methods` indica cuál de las dos puede usar.

No instales una versión sin confirmar ni escribas código basado en opciones de callback sin confirmar. Confirma las exportaciones del paquete publicado, el emisor y la configuración de claves antes de sustituir el ejemplo alojado. Los métodos de contraseña, código por correo electrónico, enlace mágico, passkey, teléfono, MFA, inicio de sesión social, step-up y agentes dependerán de la API compatible con esa versión.

## Añade otros productos

Tu backend verifica el token de acceso (consulta [tokens y JWKS](https://docs.didit.me/es/authentication/tokens-and-jwks.md)) y lee su `vendor_data`. Usa ese valor como `vendor_data` al [crear una sesión de verificación](https://docs.didit.me/es/sessions-api/create-session.md) o al [emitir un token de transacción](https://docs.didit.me/es/transaction-monitoring/sdk-transaction-submission.md). Un inicio de sesión correcto no implica que ninguno de los dos productos haya aprobado al usuario.

Antes de publicar, prueba el registro, el inicio de sesión de usuarios recurrentes, la cancelación, el state que no coincide, el código reutilizado, la contraseña olvidada, MFA, la caducidad y el cierre de sesión con tu aplicación de sandbox habilitada.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.