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

# JavaScript-Authentifizierung mit Didit: Schnellstart

> Verbinden Sie eine aktive Authentifizierungsanwendung in Didit mit der gehosteten Anmeldung per PKCE, Callback-Prüfung, Sitzungsprüfung und Logout.

> [!WARNING]
>
> Authentication ist neu: Verwenden Sie dieses Beispiel für die gehostete Anmeldung nur mit einer Anwendung, für die Authentication aktiviert ist. Das Paket `@didit-protocol/auth` ist noch nicht veröffentlicht. Die Paket-API unten ist eine Vorschau und keine installierbare Schnellstartanleitung.

## Gehostete Anmeldung konfigurieren

Registrieren Sie die genaue Callback-URL und Ihren Web-Ursprung für Ihre Sandbox-Anwendung. Kopieren Sie den Anmelde-Ursprung (`https://<slug>.sandbox.auth.didit.me`) aus der Konsole, wie in der [Übersicht](https://docs.didit.me/de/authentication/overview.md) beschrieben. Dieses Beispiel verwendet die Kryptografie-APIs des Browsers und erfordert HTTPS bzw. in der Sandbox localhost. Welche Einträge Sie registrieren müssen, erfahren Sie unter [lokale Entwicklung](https://docs.didit.me/de/authentication/overview.md#lokale-entwicklung).

Die Anwendung verwaltet `state` und den PKCE-Verifier. Die gehostete Anmeldung verwaltet die Bildschirme für Passwort, E-Mail, Passkey, Telefon, SSO und erforderliche MFA. In diesem Code darf kein API-Schlüssel stehen.

```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.");
}
```

Rufen Sie `signIn()` von Ihrer Anmeldeschaltfläche aus auf. Rufen Sie auf der registrierten Callback-Seite `handleCallback()` genau einmal auf, zeigen Sie einen Ladezustand an und geben Sie einen Fehler aus, falls der Aufruf fehlschlägt. Verwenden Sie `getSession()` für den aktuellen Benutzer und `signOut()` für die Abmeldung. Der Callback entfernt seinen Code aus der Adresszeile, bevor er eine Anfrage stellt.

Dieses minimale Beispiel speichert Tokens im Speicher und meldet den Benutzer nach einem Neuladen der Seite oder nach Ablauf des Access-Tokens erneut an. Für dauerhafte Sitzungen verwenden Sie Ihr Backend und sichere Cookies oder implementieren eine serialisierte [Refresh-Token-Rotation](https://docs.didit.me/de/authentication/tokens-and-jwks.md). Legen Sie Refresh-Tokens niemals in URLs oder Logs ab. Eine Sitzungsprüfung im Frontend steuert nur die Darstellung. Ihr Backend muss den Aufrufer bei jeder geschützten Anfrage validieren.

## Vorschau des Authentication-SDK-Releases

Der geplante `@didit-protocol/auth`-Core stellt `createDiditAuth({publishableKey})`, `signIn()`, `handleRedirectCallback()`, `getSession()`, `getToken()`, `onAuthStateChange` und `signOut()` bereit, wobei `vendorData` auf der Identität enthalten ist. Er soll automatische Geräte-Signale und einen Server-Einstiegspunkt mit `verifyToken()` ergänzen.

Der Publishable Key besteht aus `pk_live_` (Live-Anwendung) bzw. `pk_test_` (Sandbox-Anwendung), gefolgt von der base64url-Kodierung des Ursprungs Ihrer Anwendung ohne Padding.
Das SDK sendet seine API-Aufrufe an diesen Ursprung.
Der Key ist öffentlich: Er identifiziert die Anwendung und ist kein Geheimnis.

### Step-up und erneute Authentifizierung in der Vorschau

* `stepUp({ action, amount?, currency?, redirectUri? })` ruft `POST step-up/` Ihrer Anwendung auf, um zu prüfen, ob `action` eine Identitätsprüfung erfordert.
  `action` ist `payout`, `bank` oder `contact`. Bei einer Auszahlung ist `amount` erforderlich.
  Wenn eine Ihrer Step-up-Regeln greift, leitet der Aufruf zur Verifizierungsseite weiter, die Didit zurückgibt.
* `handleStepUpCallback(url?)` läuft auf der Seite, zu der die Person zurückkehrt.
  Sie liest `?step_up=<id>`, entfernt den Parameter aus der Adresszeile und ruft das Ergebnis mit `GET step-up/{id}/` ab.
* `reauthenticate({ method? })` meldet dieselbe Person erneut an, entweder auf der gehosteten Seite (`method: "redirect"`, Standard) oder mit einem Passkey (`method: "passkey"`, nur auf der Didit-Anmeldedomain Ihrer Anwendung).
  Nach der gehosteten Seite schließen Sie den Vorgang mit `handleRedirectCallback()` ab.
  Schließt ihn eine andere Person ab, wird mit `step_up_user_mismatch` abgelehnt, und die ursprüngliche Sitzung bleibt bestehen.

Beide Step-up-Methoden liefern `{ id, status, approved, rule, method }` zurück. `status` ist `not_required`, `pending`, `approved`, `review`, `declined` oder `expired`.
`redirectUri` ist standardmäßig die Redirect-Adresse des Clients und muss exakt mit einer der registrierten Redirect-Adressen Ihrer Anwendung übereinstimmen. Ist eine Prüfung erforderlich, lehnt Didit jede andere Adresse ab.
Bevor Ihr Backend auf einen Step-up reagiert, liest es ihn erneut mit `GET step-up/{id}/` und dem Access-Token der Person, denn ein vom Browser gemeldetes Ergebnis kann verändert worden sein.

Eine Headless-Anmeldung kann außerdem `protection_required` zurückgeben, wenn die Schutzregeln Ihrer Anwendung dies auslösen.
Die Person schließt sie dann mit dem Code ab, den Didit ihr per E-Mail geschickt hat (`protection.verify({ code })`), oder mit einem Passkey (`protection.passkey()`). `methods` gibt an, welche der beiden Optionen sie verwenden können.

Installieren Sie keine vermutete Version und schreiben Sie keinen Code gegen vermutete Callback-Optionen. Bestätigen Sie vor dem Ersetzen des Beispiels für die gehostete Anmeldung die Exporte des veröffentlichten Pakets, den Issuer und die Key-Konfiguration. Passwort, E-Mail-Code, Magic Link, Passkey, Telefon, MFA, Social Login, Step-up und Agent-Methoden hängen von der unterstützten API des jeweiligen Releases ab.

## Weitere Produkte hinzufügen

Ihr Backend verifiziert das Access-Token (siehe [Tokens und JWKS](https://docs.didit.me/de/authentication/tokens-and-jwks.md)) und liest dessen `vendor_data`. Verwenden Sie diesen Wert als `vendor_data`, wenn Sie [eine Verifizierungssitzung erstellen](https://docs.didit.me/de/sessions-api/create-session.md) oder [ein Transaktions-Token ausstellen](https://docs.didit.me/de/transaction-monitoring/sdk-transaction-submission.md). Eine erfolgreiche Anmeldung bedeutet nicht, dass eines dieser Produkte den Benutzer genehmigt hat.

Testen Sie vor der Auslieferung Registrierung, erneute Anmeldung, Abbruch, einen nicht übereinstimmenden State, einen wiederverwendeten Code, die Passwort-Wiederherstellung, MFA, Ablauf und Abmeldung in Ihrer aktivierten Sandbox-Anwendung.


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