Authentifizierung
Übersicht
Abschnitt betitelt „Übersicht“Das Modul client.auth verwaltet die Benutzerauthentifizierung, Token-Verwaltung und Sitzungspersistenz. Sobald sich ein Benutzer anmeldet, enthalten alle nachfolgenden Datenanfragen automatisch das JWT.
Das SDK speichert Sitzungen standardmäßig in localStorage und erneuert Tokens automatisch vor ihrem Ablauf.
E-Mail / Passwort
Abschnitt betitelt „E-Mail / Passwort“Anmelden
Abschnitt betitelt „Anmelden“const { user, accessToken, refreshToken } = await client.auth.signInWithEmail( "user@example.com", "password");console.log(user.uid, user.email);Registrieren
Abschnitt betitelt „Registrieren“const { user, confirmationRequired } = await client.auth.signUp( "user@example.com", "password", "Jane Doe" // optional displayName);Wenn requireEmailVerification aktiviert ist,
gibt es keine Sitzung, bis die Adresse bestätigt wurde: confirmationRequired ist true und user ist null. Bitten Sie die Person daher, ihre E-Mails zu prüfen. Andernfalls ist confirmationRequired false und user ist das angemeldete Konto. In Version 0.23 löst signUp zu { user, accessToken, refreshToken } auf und meldet den Benutzer immer an.
OAuth-Anbieter
Abschnitt betitelt „OAuth-Anbieter“Das SDK enthält dedizierte Methoden für gängige OAuth-Anbieter sowie ein generisches signInWithOAuth() für benutzerdefinierte Anbieter.
Unterstützt drei Aufrufvarianten:
// ID-token flow (One Tap / Sign In With Google button)await client.auth.signInWithGoogle({ idToken: googleIdToken });
// Access-token flow (popup)await client.auth.signInWithGoogle({ accessToken: googleAccessToken });
// Authorization code flow (most secure, server-side exchange)await client.auth.signInWithGoogle({ code: authCode, redirectUri: "https://..." });Weitere Anbieter
Abschnitt betitelt „Weitere Anbieter“Jeder Anbieter folgt dem Authorization-Code-Flow mit (code, redirectUri):
await client.auth.signInWithGitHub(code, redirectUri);await client.auth.signInWithMicrosoft(code, redirectUri);await client.auth.signInWithFacebook(code, redirectUri);await client.auth.signInWithLinkedin(code, redirectUri);await client.auth.signInWithDiscord(code, redirectUri);await client.auth.signInWithGitLab(code, redirectUri);await client.auth.signInWithBitbucket(code, redirectUri);await client.auth.signInWithSlack(code, redirectUri);await client.auth.signInWithSpotify(code, redirectUri);Twitter erfordert zusätzlich den PKCE-Code-Verifier:
await client.auth.signInWithTwitter(code, redirectUri, codeVerifier);Im Browser öffnet signInWithApplePopup() das Popup von Apple, prüft state und
meldet sich mit dem Code an. Rufen Sie es über einen Click-Handler auf. Rufen Sie beim Mounten
preloadAppleSignIn() auf, da Safari Popups blockiert, die auf das Herunterladen eines Skripts warten:
import { preloadAppleSignIn } from "@rebasepro/client";
void preloadAppleSignIn(); // on mountawait client.auth.signInWithApplePopup({ clientId: "com.example.web" }); // on clickOhne clientId liest das SDK die Services-ID von /auth/config, was
das Popup verzögert. Die Redirect-URI ist standardmäßig der Ursprung der Seite plus / und
muss eine Return-URL auf der Services-ID sein (HTTPS, niemals localhost). Ein geschlossenes
Popup wird mit dem Code APPLE_SIGN_IN_CANCELLED abgelehnt.
Eine native iOS- oder macOS-App sendet den Autorisierungscode aus Apples nativem
Sign-In mit ihrer Bundle-ID. Die Bundle-ID muss in APPLE_BUNDLE_IDS aufgeführt sein:
await client.auth.signInWithApple({ code: credential.authorizationCode, bundleId: "com.example.ios", user: { name: { firstName: "Jane" } } // sent by Apple on the first sign-in only});Generisches OAuth
Abschnitt betitelt „Generisches OAuth“Für jeden im Backend registrierten Anbieter:
await client.auth.signInWithOAuth("custom-provider", { code: authCode, redirectUri: "https://myapp.com/callback"});Magic Links
Abschnitt betitelt „Magic Links“Ein Ein-Klick-Anmeldelink per E-Mail. Der Link lautet immer <base>/auth/magic-link?token=…, wobei <base> die email.magicLinkUrl des Backends ist oder dessen Basis-URL zum Zurücksetzen des Passworts (FRONTEND_URL in der Laufzeitumgebung), falls diese nicht gesetzt ist. Es gibt kein anfragebezogenes redirectTo. Stellen Sie diesen Pfad in Ihrem Frontend bereit und übergeben Sie das Token zurück, um es gegen eine Sitzung einzutauschen. Das CMS stellt dies bereit und meldet sich an (über den Code-Schritt, falls ein zweiter Faktor vorhanden ist); andere Frontends benötigen eine Landingpage.
// 1. Ask for the link.await client.auth.sendMagicLink("user@example.com");
// 2. On the landing page, trade the token for a session.const token = new URLSearchParams(location.search).get("token")!;const { user } = await client.auth.verifyMagicLink(token);sendMagicLink antwortet gleich, unabhängig davon, ob für die Adresse ein
Konto existiert oder nicht. Das ist Absicht: Ein Endpunkt, der „Benutzer existiert nicht“ meldet,
wäre ein Orakel für die Aufzählung von Benutzerkonten, nutzen Sie das Ergebnis daher nicht,
um einer Person mitzuteilen, ob sie registriert ist — der Endpunkt weiß es nicht.
Für den Versand muss im Backend ein E-Mail-Dienst konfiguriert sein, andernfalls
antwortet sendMagicLink mit 503 EMAIL_NOT_CONFIGURED.
Einmalcodes
Abschnitt betitelt „Einmalcodes“Ein sechsstelliger Code per E-Mail für dieselbe Aufgabe, wenn ein Link unpraktisch ist — eine native App, ein zweites Gerät, ein Browser, der Links verändert.
const { expiresInSeconds } = await client.auth.sendEmailOtp("user@example.com");
// The address goes back with the code, because the code is only valid for it.const { user } = await client.auth.verifyEmailOtp("user@example.com", "418293");Das Mitsenden der Adresse mit dem Code stellt sicher, dass ein sechsstelliger Rateversuch ein Versuch gegen ein bestimmtes Konto bleibt und nicht gegen alle Konten gleichzeitig.
Anonyme Sitzungen
Abschnitt betitelt „Anonyme Sitzungen“Melden Sie einen Besucher ganz ohne Zugangsdaten an, damit er die App nutzen kann, bevor er einen Grund zur Registrierung hat:
const { user } = await client.auth.signInAnonymously();user.isAnonymous; // trueDas Konto ist echt: Es hat eine ID, Rollen und eine Sitzung, sodass Row-Level Security seine Zeilen genauso eingrenzt wie bei einem registrierten Benutzer. Was es nicht hat, ist ein Rückweg — niemand kann sich ein zweites Mal als dieses Konto anmelden, sodass alles, was ihm gehört, mit der Sitzung verloren geht.
linkAnonymous sorgt dafür, dass das Konto nicht länger flüchtig ist. Der Benutzer behält seine ID,
sodass alles, was er im anonymen Zustand erstellt hat, in seinem Besitz bleibt:
await client.auth.linkAnonymous("user@example.com", "correct-horse-battery");| Fehler | Bedeutung |
|---|---|
ANONYMOUS_AUTH_DISABLED (403) |
Das Backend hat die anonyme Authentifizierung nicht aktiviert oder seit der Anmeldung dieses Gasts deaktiviert: Ein Gast wird nur dann zu einem Konto, wenn allowAnonymous aktiviert ist |
REGISTRATION_DISABLED (403) |
Die Registrierung ist im Backend deaktiviert, und die Umwandlung in ein Konto ist eine Registrierung |
NOT_ANONYMOUS (400) |
Die aktuelle Sitzung gehört zu einem regulären Konto |
EMAIL_EXISTS (409) |
Für die Adresse existiert bereits ein Konto — melden Sie sich stattdessen bei diesem an |
Ein Gast, der nie wiederkehrt, bleibt als Zeile bestehen. Ein Administrator kann
diese mit client.admin.listGuests(), client.admin.deleteGuest(uid) und
client.admin.deleteGuests({ lastSeenBefore }) oder auf Rebase Cloud mit
rebase cloud guests bereinigen. Diese Methoden betreffen ausschließlich Gäste,
und deleteGuests arbeitet stapelweise: Wiederholen Sie dies, solange remaining ungleich 0 ist,
wobei offset darauf gesetzt wird, wie viele bisher übersprungen wurden.
Verknüpfen eines Anbieters mit einem bestehenden Konto
Abschnitt betitelt „Verknüpfen eines Anbieters mit einem bestehenden Konto“signInWithGoogle und ähnliche Methoden melden einen Benutzer an. linkProvider verknüpft eine
Identität eines Drittanbieters mit dem bereits angemeldeten Konto, sodass dieselbe Person über
beide Wege zurückkehren kann:
await client.auth.linkProvider("google", { idToken });Die Sitzung beweist bereits den Kontobesitz, daher muss der Anbieter im Gegensatz zur Anmeldung
die E-Mail-Adresse nicht verifiziert haben, und die beiden Adressen müssen nicht übereinstimmen.
Es verhält sich idempotent erfolgreich (alreadyLinked: true), wenn diese Identität bereits mit
diesem Konto verknüpft ist, und bricht mit IDENTITY_ALREADY_LINKED (409) ab, wenn sie zu einem anderen gehört.
Suchen eines Benutzers nach E-Mail-Adresse
Abschnitt betitelt „Suchen eines Benutzers nach E-Mail-Adresse“const profile = await client.auth.findUserByEmail("user@example.com");// { uid, displayName, photoURL } | nullDrei nicht-sensible Felder und sonst nichts — genug, um vor dem Versenden einer
Einladung „Sie laden Jane ein“ anzuzeigen. Opt-in: nur für angemeldete Aufrufer und ein 404-Fehler,
es sei denn, das Backend setzt AUTH_ALLOW_USER_LOOKUP=true (auth.allowUserLookup).
Multi-Faktor-Authentifizierung
Abschnitt betitelt „Multi-Faktor-Authentifizierung“Einrichten eines Faktors, der zweite Schritt einer Anmeldung, Wiederherstellungscodes und das Entfernen eines Faktors: Multi-Faktor-Authentifizierung.
Abmelden
Abschnitt betitelt „Abmelden“await client.auth.signOut();Dies widerruft das Refresh-Token auf dem Server, leert die lokale Sitzung und löst ein SIGNED_OUT-Event aus.
Sitzungsverwaltung
Abschnitt betitelt „Sitzungsverwaltung“Aktuelle Sitzung abrufen
Abschnitt betitelt „Aktuelle Sitzung abrufen“const session = client.auth.getSession();// { accessToken, refreshToken, expiresAt, user } | nullSpeichern Sie niemals das Sitzungsobjekt dauerhaft. getSession() ist eine Momentaufnahme. Jede Erneuerung
des Access-Tokens (etwa einmal pro Stunde) ersetzt die Sitzung durch ein neues Objekt. Eine Sitzung, die seit dem
Laden der Seite behalten wird, enthält daher ein Token, das der Server nach Ablauf ablehnt, und die App wirkt abgemeldet.
Lesen Sie die Sitzung ab, wenn Sie sie benötigen.
Senden des Tokens an eigene Routen
Abschnitt betitelt „Senden des Tokens an eigene Routen“Der Aufruf einer Funktion in backend/functions/ erfordert keine Token-Verwaltung:
client.functions.invoke erneuert das Token vor dem Senden und versucht es bei einem 401-Fehler
einmal erneut.
const saved = await client.functions.invoke("progress", { level: 3 }, { path: "save" });Fragen Sie bei allen anderen Anfragen das Token jedes Mal mit getAccessToken() an.
Es erneuert ein abgelaufenes oder bald ablaufendes Token, wartet auf die beim Laden
wiederhergestellte Sitzung und gibt null zurück, wenn niemand angemeldet ist.
const token = await client.auth.getAccessToken();await fetch("https://other.example.com/upload", { method: "POST", headers: token ? { Authorization: `Bearer ${token}` } : {}, body: file});Aktuellen Benutzer abrufen (servervalidiert)
Abschnitt betitelt „Aktuellen Benutzer abrufen (servervalidiert)“const user = await client.auth.getUser();// Fetches the user from the backend (GET /auth/me)Benutzerprofil aktualisieren
Abschnitt betitelt „Benutzerprofil aktualisieren“const updatedUser = await client.auth.updateUser({ displayName: "Jane Doe", photoURL: "https://example.com/avatar.jpg"});Token erneuern
Abschnitt betitelt „Token erneuern“Die Token-Erneuerung erfolgt automatisch, Sie können sie jedoch manuell auslösen:
const session = await client.auth.refreshSession();Eine Anfrage wird niemals mit einem Token gesendet, von dem der Client weiß, dass es abgelaufen ist: Anfragen teilen sich eine Aktualisierung und werden einmal mit dem neuen Token gesendet. Ein Token, das der Server vorzeitig ablehnt, erhält dennoch eine Aktualisierung und anschließend einen erneuten Versuch pro Anfrage.
Wo die Sitzung gespeichert wird: authFlowMode
Abschnitt betitelt „Wo die Sitzung gespeichert wird: authFlowMode“const client = createRebaseClient({ baseUrl: API_URL, auth: { authFlowMode: "cookie" }});| Modus | Wo sich das Refresh-Token befindet | Standard |
|---|---|---|
"cookie" |
Ein HttpOnly-Cookie, das das Backend setzt. Skripte auf Ihrer Seite können es nicht lesen, was es XSS-sicher macht | Im Browser |
"json" |
Wird im Response-Body zurückgegeben und im storage aufbewahrt (standardmäßig localStorage) |
Außerhalb des Browsers (Node, Worker, React Native) sowie im Browser, wenn Sie Ihren eigenen storage übergeben |
Beide Seiten müssen übereinstimmen. Der Cookie-Modus erfordert auth.cookieAuth im
Backend, und die Rebase-Runtime, auf der Rebase Cloud läuft, schaltet dies immer ein.
Der Json-Modus erfordert ein Backend ohne diese Option: Bei einem cookieAuth-Backend wird
einem Json-Client kein Refresh-Token übergeben, und seine Sitzung endet, sobald das Access-Token
abläuft (ca. eine Stunde nach der Anmeldung). Wenn die Antwort auf eine Anmeldung zeigt, dass die
Modi nicht übereinstimmen, protokolliert der Client einen Fehler mit dem Hinweis, welcher Modus verwendet werden soll.
Die Übergabe eines eigenen storage hält einen Browser-Client im Json-Modus. Dies ist für einen
zweiten Client auf der Seite gedacht, der seine eigene Anmeldung getrennt vom Cookie der Seite
verwaltet: Im Cookie-Modus würde in diesem Speicher nichts abgelegt werden.
Auf die Wiederherstellung der Sitzung warten
Abschnitt betitelt „Auf die Wiederherstellung der Sitzung warten“Eine wiederhergestellte Sitzung ist beim ersten Rendern noch nicht verfügbar. getSession() ist
synchron, weshalb es beim Laden der Seite null zurückgibt, während die Wiederherstellung noch
läuft — und im Cookie-Modus läuft immer eine Wiederherstellung, da sich das Refresh-Token
in einem Cookie befindet, das die Seite nicht lesen kann, sodass der Client beim Server
ein frisches Access-Token anfordern muss.
Das synchrone Auslesen führt bei jedem Neuladen zu einem kurzen Aufblitzen des Abmeldezustands:
// Wrong: renders the signed-out view for one round trip, every reload.const session = client.auth.getSession();if (!session) return <SignIn />;isInitialized() löst auf, sobald der Client den Versuch abgeschlossen hat —
unabhängig davon, ob eine Sitzung gefunden wurde oder nicht:
async function currentUser() { await client.auth.isInitialized(); return client.auth.getSession()?.user ?? null;}In React entspricht das einem Effect:
import { useEffect, useState } from "react";
function useCurrentUser() { const [user, setUser] = useState<User | null>(null); const [loading, setLoading] = useState(true);
useEffect(() => { let cancelled = false; client.auth.isInitialized().then(() => { if (cancelled) return; setUser(client.auth.getSession()?.user ?? null); setLoading(false); }); return () => { cancelled = true; }; }, []);
return { user, loading };}useRebaseAuthController in @rebasepro/app übernimmt dies bereits, sodass eine auf
der generierten Vorlage basierende App dies automatisch enthält. Datenanfragen müssen nicht warten: Eine Anfrage,
die während der Wiederherstellung gestellt wird, wird gesendet, sobald diese abgeschlossen ist — als wiederhergestellter
Benutzer oder anonym —, sodass ein erstes Rendern niemals eine öffentliche Liste anstelle der benutzereigenen Daten anzeigt.
Eine Wiederherstellung mit Erneuerung (ein abgelaufenes gespeichertes Token oder Cookie-Modus) erreicht
onAuthStateChange als TOKEN_REFRESHED; ein noch gültiges gespeichertes Token wird stillschweigend
übernommen. Ein Listener kann Ihnen daher nicht mitteilen, ob die Wiederherstellung abgeschlossen ist: Ein Startvorgang,
der nichts auslöst, ist nicht von einem noch laufenden zu unterscheiden. Warten Sie für diesen Status auf isInitialized()
und verwenden Sie den Listener für spätere Änderungen.
restoreOutcome() gibt an, wie die Wiederherstellung endete, sobald isInitialized() aufgelöst
wurde: "restored", "none" (nichts wiederherzustellen), "refused" (der Server hat die Sitzung abgelehnt)
oder "unreachable" (der Server konnte nicht erreicht werden, daher wurde die Sitzung weder bestätigt noch
abgelehnt). Im Cookie-Modus ist "unreachable" ohne Sitzung der einzige Fall, in dem nicht sicher feststeht,
ob der Benutzer tatsächlich abgemeldet ist:
await client.auth.isInitialized();if (!client.auth.getSession() && client.auth.restoreOutcome() === "unreachable") { console.log("Offline: could not check the session.");}Auth-Status-Listener
Abschnitt betitelt „Auth-Status-Listener“Reagieren Sie auf Authentifizierungsänderungen in Ihrer gesamten Anwendung:
const unsubscribe = client.auth.onAuthStateChange((event, session) => { // event: "SIGNED_IN" | "SIGNED_OUT" | "TOKEN_REFRESHED" | "USER_UPDATED" console.log("Auth event:", event); console.log("Session:", session?.user?.email);});
// Stop listeningunsubscribe();| Event | Wann |
|---|---|
SIGNED_IN |
Eine Anmeldung oder Registrierung wurde abgeschlossen |
TOKEN_REFRESHED |
Das Access-Token wurde erneuert — einschließlich der stillen Erneuerung, die eine Sitzung beim Laden der Seite wiederherstellt |
USER_UPDATED |
updateUser() hat das Profil geändert, linkAnonymous() hat aus einem Gast ein Konto gemacht, changeEmail() hat eine Adressänderung initiiert oder confirmEmailChange() hat dieses Konto auf die neue Adresse umgestellt |
SIGNED_OUT |
Eine Abmeldung, revokeAllSessions() oder eine Aktualisierung, die endgültig fehlgeschlagen ist |
Passwortverwaltung
Abschnitt betitelt „Passwortverwaltung“Passwort vergessen
Abschnitt betitelt „Passwort vergessen“const { success, message } = await client.auth.resetPasswordForEmail( "user@example.com");Passwort zurücksetzen (mit Token)
Abschnitt betitelt „Passwort zurücksetzen (mit Token)“const { success, message } = await client.auth.resetPassword( resetToken, "newSecurePassword");Passwort ändern (authentifiziert)
Abschnitt betitelt „Passwort ändern (authentifiziert)“const { success, message } = await client.auth.changePassword( "oldPassword", "newPassword");Jede andere Sitzung des Kontos wird beendet: Jeder andere Sitzungsinhaber muss sich
mit dem neuen Passwort anmelden. Dieses Gerät bleibt angemeldet. Der Server antwortet mit einer
neuen Sitzung, die der Client übernimmt (was TOKEN_REFRESHED auslöst).
E-Mail-Verifizierung
Abschnitt betitelt „E-Mail-Verifizierung“Bei der Registrierung wird dem neuen Konto der Verifizierungslink per E-Mail zugesendet,
wenn E-Mail konfiguriert ist. sendVerificationEmail() versendet ihn erneut.
// Send verification email to the current userawait client.auth.sendVerificationEmail();
// Verify with the token from the email link. Signed in as that account, this// keeps everything on it.const { passwordRemoved } = await client.auth.verifyEmail(token);
// Signed out, an account that holds a password answers PROOF_REQUIRED:try { await client.auth.verifyEmail(token);} catch (e) { if (e instanceof Error && "code" in e && e.code === "PROOF_REQUIRED") { // Keep the password, and sign in: await client.auth.verifyEmail(token, { password }); // …or verify without it, which removes it: // await client.auth.verifyEmail(token, { removeUnproven: true }); }}Der Link bestätigt den Zugriff auf das Postfach, nicht wer die Adresse registriert hat. Ein Passwort, das weder durch die Sitzung noch durch den Aufruf bestätigt wird, wird daher entfernt statt beibehalten — siehe E-Mail-Verifizierung.
Bei einem Backend mit requireEmailVerification löst signUp() mit
{ confirmationRequired: true, user: null } und ohne Sitzung auf: Das Konto
wird angemeldet, sobald dem Link mit dem zugehörigen Passwort gefolgt wird.
Ändern der E-Mail-Adresse
Abschnitt betitelt „Ändern der E-Mail-Adresse“Ein angemeldeter Benutzer überträgt sein eigenes Konto auf eine andere Adresse. Es ändert sich nichts, bis die neue Adresse bestätigt wird:
// Mails a link to the new address, and a notice to the current oneconst { pendingEmail, expiresAt } = await client.auth.changeEmail("jane@new.example");
// On the page the link opens (<frontend>/confirm-email-change?token=…):const { email, removedProviders } = await client.auth.confirmEmailChange(token);Der Link ist 24 Stunden gültig; getUser() meldet die ausstehende Adresse als
pendingEmail. Die Bestätigung erfordert keine Sitzung, und ein als dieses Konto
angemeldeter Client übernimmt die neue Adresse und löst USER_UPDATED aus. Mögliche
Ablehnungsgründe sind unter Ändern einer E-Mail-Adresse aufgeführt.
Sitzungsverwaltung (Multi-Device)
Abschnitt betitelt „Sitzungsverwaltung (Multi-Device)“// List all active sessions, one per sign-inconst sessions = await client.auth.getSessions();// [{ id, userAgent, ipAddress, createdAt, isCurrentSession }, …]
// Revoke a specific sessionawait client.auth.revokeSession(sessionId);
// Revoke ALL sessions (logs out everywhere)await client.auth.revokeAllSessions();Jedes Access-Token benennt die Anmeldung, zu der es gehört, sodass genau ein Eintrag
isCurrentSession: true hat: das anfragende Gerät. Das Widerrufen einer Sitzung beendet das
Refresh-Token dieses Geräts sowie dessen Access-Token gemeinsam ab der nächsten Anfrage
über HTTP und über einen offenen Realtime-Socket. Das Abmelden (signOut()) bewirkt dasselbe
für das Gerät, das sich abmeldet. Ein vor dieser Version ausgestelltes Access-Token benennt
keine Sitzung; es funktioniert weiter, bis es innerhalb der Stunde abläuft.
Auth-Konfiguration
Abschnitt betitelt „Auth-Konfiguration“Fragen Sie die Authentifizierungskonfiguration des Backends ab:
const config = await client.auth.getAuthConfig();// {// hasBuiltInAuthRoutes: boolean,// emailPasswordLogin: boolean,// registrationEnabled: boolean, // open right now, bootstrap window included// passwordReset: boolean, // needs an email service// adminPasswordReset: boolean,// sessionManagement: boolean,// profileUpdate: boolean,// emailVerification: boolean,// magicLink: boolean, emailOtp?: boolean,// anonymousLogin: boolean, enabledProviders: string[],// providerClientIds?: Record<string, string>, // public ids, e.g. { apple: Services ID }// externalLoginUrl?: string, needsSetup?: boolean, storage?: boolean// }Benutzerdefinierter Sitzungsspeicher
Abschnitt betitelt „Benutzerdefinierter Sitzungsspeicher“Standardmäßig werden Sitzungen in localStorage gespeichert. Sie können dies über die Option auth anpassen:
import { createRebaseClient, createCookieStorage } from "@rebasepro/client";
// Use cookies instead of localStorageconst client = createRebaseClient({ baseUrl: import.meta.env.VITE_API_URL, auth: { storage: createCookieStorage({ path: "/", sameSite: "Lax", secure: true }), autoRefresh: true, // default: true persistSession: true // default: true }});Eigenen Auth-Anbieter verwenden
Abschnitt betitelt „Eigenen Auth-Anbieter verwenden“Clerk, Firebase Auth oder eine Sitzung, die Ihre App bereits hat, mit einem Token-Getter
anstelle von client.auth: Eigener Auth-Anbieter.
Struktur des User-Objekts
Abschnitt betitelt „Struktur des User-Objekts“// Canonical type — import from @rebasepro/typesinterface User { uid: string; email: string | null; displayName: string | null; photoURL: string | null; providerId: string; isAnonymous: boolean; emailVerified?: boolean; pendingEmail?: string | null; // an address change waiting for its link roles?: string[]; // text[] from the users table metadata?: Record<string, unknown>;}Nächste Schritte
Abschnitt betitelt „Nächste Schritte“- Daten abfragen — CRUD-Operationen und Query-Builder
- Echtzeit-Abonnements — Live-Daten mit WebSockets
- Authentifizierungs-Backend — Serverseitige Auth-Konfiguration