> ## 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.

# Guia rápido de autenticação em JavaScript com a Didit

> Conecte uma aplicação de Authentication ativa da Didit ao login hospedado com PKCE, validação de callback, checagem de sessão e logout.

> [!WARNING]
>
> O Authentication é recente: use este exemplo de fluxo hospedado com uma aplicação com o Authentication ativado. O pacote `@didit-protocol/auth` ainda não foi publicado; a API do pacote abaixo é uma prévia, não um quickstart instalável.

## Configurar o login hospedado

Registre a URL de retorno exata e a origem web da sua aplicação de sandbox. Copie a origem de login dela (`https://<slug>.sandbox.auth.didit.me`) no console, como descrito na [visão geral](https://docs.didit.me/pt-br/authentication/overview.md). Este exemplo usa as APIs de criptografia do navegador e exige HTTPS, ou localhost no sandbox: veja em [desenvolvimento local](https://docs.didit.me/pt-br/authentication/overview.md#desenvolvimento-local) o que registrar.

A aplicação é responsável pelo `state` e pelo verificador PKCE. O login hospedado é responsável pelas telas de senha, e-mail, passkey, telefone, SSO e MFA obrigatório. Nenhuma chave de API deve estar neste 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.");
}
```

Chame `signIn()` no seu botão de login. Na página de retorno registrada, chame `handleCallback()` uma única vez, exiba um estado de carregamento e mostre o erro caso ela falhe. Use `getSession()` para obter o usuário atual e `signOut()` para fazer logout. A página de retorno remove o código da barra de endereço antes de fazer uma requisição.

Este exemplo mínimo mantém os tokens em memória e faz login novamente após recarregar a página ou quando o token de acesso expira. Para sessões persistentes, use seu backend e cookies seguros ou implemente a [rotação serializada de refresh](https://docs.didit.me/pt-br/authentication/tokens-and-jwks.md). Nunca coloque refresh tokens em URLs ou logs. Uma verificação de sessão no frontend controla apenas a apresentação; seu backend deve validar quem faz a chamada em toda requisição protegida.

## Prévia de lançamento do SDK de autenticação

O núcleo planejado do `@didit-protocol/auth` expõe `createDiditAuth({publishableKey})`, `signIn()`, `handleRedirectCallback()`, `getSession()`, `getToken()`, `onAuthStateChange` e `signOut()`, com `vendorData` na identidade. A intenção é adicionar sinais automáticos do dispositivo e um ponto de entrada no servidor com `verifyToken()`.

A chave publicável é `pk_live_` (aplicação de produção) ou `pk_test_` (aplicação de sandbox) seguida da codificação base64url, sem padding, da origem da sua aplicação.
O SDK envia suas chamadas de API para essa origem.
A chave é pública: ela identifica a aplicação e não é um segredo.

### Step-up e reautenticação na prévia

* `stepUp({ action, amount?, currency?, redirectUri? })` chama o `POST step-up/` da sua aplicação para perguntar se `action` exige uma verificação de identidade.
  `action` é `payout`, `bank` ou `contact`, e um payout exige `amount`.
  Quando uma das suas regras de step-up se aplica, ele navega até a página de verificação que a Didit retorna.
* `handleStepUpCallback(url?)` é executado na página para a qual a pessoa retorna.
  Ele lê `?step_up=<id>`, remove esse parâmetro da barra de endereço e lê o resultado com `GET step-up/{id}/`.
* `reauthenticate({ method? })` autentica a mesma pessoa novamente, na página hospedada (`method: "redirect"`, o padrão) ou com uma passkey (`method: "passkey"`, apenas no domínio de login da Didit da sua aplicação).
  Após a página hospedada, conclua com `handleRedirectCallback()`.
  Se outra pessoa concluir, a operação é rejeitada com `step_up_user_mismatch` e a sessão original é mantida.

Os dois métodos de step-up retornam `{ id, status, approved, rule, method }`, em que `status` é `not_required`, `pending`, `approved`, `review`, `declined` ou `expired`.
`redirectUri` usa por padrão o endereço de redirecionamento do cliente e deve corresponder exatamente a um dos endereços de redirecionamento registrados da sua aplicação: quando uma verificação é necessária, a Didit recusa qualquer outro endereço.
Antes de agir com base em um step-up, seu backend lê o step-up novamente com `GET step-up/{id}/` e o token de acesso da pessoa, porque um resultado informado pelo navegador pode ser alterado.

Um login headless também pode retornar `protection_required` quando as regras de proteção da sua aplicação o sinalizam.
A pessoa então o conclui com o código que a Didit enviou por e-mail (`protection.verify({ code })`) ou com uma passkey (`protection.passkey()`), e `methods` lista qual dos dois ela pode usar.

Não instale uma versão presumida nem escreva código com base em opções de retorno presumidas. Confirme os exports do pacote publicado, o emissor e a configuração de chaves antes de substituir o exemplo hospedado. Os métodos de senha, código por e-mail, link mágico, passkey, telefone, MFA, login social, step-up e agentes dependerão da API compatível com esse lançamento.

## Adicionar outros produtos

Seu backend verifica o token de acesso (veja [tokens e JWKS](https://docs.didit.me/pt-br/authentication/tokens-and-jwks.md)) e lê o `vendor_data` dele. Use esse valor como `vendor_data` ao [criar uma sessão de verificação](https://docs.didit.me/pt-br/sessions-api/create-session.md) ou ao [gerar um token de transação](https://docs.didit.me/pt-br/transaction-monitoring/sdk-transaction-submission.md). Um login bem-sucedido não significa que um ou outro desses produtos tenha aprovado o usuário.

Antes de publicar, teste cadastro, login de retorno, cancelamento, state divergente, código reutilizado, esqueci a senha, MFA, expiração e logout na sua aplicação de sandbox ativada.


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