Um Capacitor Apps eine Authentifizierung hinzuzufügen, wähle eine Identitätsquelle (dein eigenes Backend, einen Hosted Service wie Firebase, Supabase oder Neon, einen OIDC-Provider wie Auth0, Okta oder Entra ID oder eine selbst gehostete Library wie Better Auth). Nutze native Plugins für alles, was eine Login-Seite des Providers öffnet, verifiziere Tokens auf einem Server und speichere die Session im Keychain oder Keystore. Biometrie und Passkeys machen den nächsten Login dann blitzschnell.
Dieser Guide ordnet jede gängige Option dem passenden Capacitor Plugin und Flow zu, inklusive code für die Teile, die in jeder App gleich sind: der Login-Call, die Token-Verifizierung, das Session-Storage und der biometrische Unlock. Der Stand ist Capacitor 8 im Oktober 2026. Jeder Provider hat unten verlinkte Schritt-für-Schritt-Anleitungen.
Der Auth-Flow, den jede Capacitor App am Ende nutzt
Egal welchen Provider du wählst, das Schema bleibt gleich:
- Identifiziere den User: über ein natives Social Sheet, eine Provider-Login-Seite im System-Browser, einen Passkey-Prompt oder ein Formular, das E-Mail und Passwort übermittelt.
- Beweis erbringen: einen ID-Token, eine code zur Autorisierung oder einen Session-Token von deinem Auth-Server.
- Verifiziere auf dem Server: prüfe Signatur, Issuer, Audience und Ablaufzeit, dann erstelle oder finde den User.
- Session ausstellen: dein eigenes Token oder die Tokens des Providers, mit einer Refresh-Strategie.
- Speichere es sicher auf dem Device und hänge es an API Calls an.
- Schneller entsperren beim nächsten Mal per Biometrie, und Logout sowie Account-Löschung abwickeln.
Die Schritte 1 und 2 hängen vom Provider ab. Die Schritte 3 bis 6 liegen in deiner Verantwortung – außer bei einem voll gehosteten BaaS, wo SDK den Großteil übernimmt.
Warum WebView-Login-Seiten scheitern
Eine Capacitor-App führt deinen Web-code in einem WKWebView (iOS) oder Android WebView mit lokalem Origin aus (capacitor://localhost oder https://localhost). Das Laden der Login-Seite eines Providers in diesem WebView verursacht drei Probleme:
- Google gibt zurück
disallowed_useragentund weigert sich, die Seite anzuzeigen. - Die App kann nicht beweisen, dass die Seite vom echten Provider stammt; deshalb empfiehlt RFC 8252 nativen Apps den System-Browser.
- Ein Full-Page-Redirect navigiert aus deiner gebündelten App heraus, und der State geht verloren.
Daher nutzt jeder Flow unten entweder ein natives SDK (Apple, Google, Facebook) oder eine System-Browser-Session (ASWebAuthenticationSession auf iOS, Chrome Custom Tabs auf Android), das über ein Custom Scheme zur App zurückkehrt.
Deine Optionen im Überblick
| Ansatz | Ideal für | Capacitor Plugin | Backend-Aufwand | Anleitung |
|---|---|---|---|---|
| Mit Apple anmelden | Jede iOS-App mit Third-Party-Login | @capgo/capacitor-social-login |
ID-Token verifizieren | Apple-Guide |
| Google Sign-In | Consumer-Apps, Android zuerst | @capgo/capacitor-social-login |
ID-Token verifizieren | Google-Guide |
| Auth0 | Hosted Login mit vielen Verbindungen | @capgo/capacitor-social-login (OAuth2) |
Access-Tokens validieren | Auth0-Guide |
| Okta | Workforce- und B2B-SSO | @capgo/capacitor-social-login (OAuth2) |
Access-Tokens validieren | Okta-Guide |
| Microsoft Entra ID | Microsoft 365-Organisationen | @capgo/capacitor-social-login (OAuth2) |
Access Tokens validieren, Graph | Entra-ID-Guide |
| Better Auth | Self-hosted, eigene User-Datenbank | better-auth Client + Social Login |
Better Auth Server ausführen | Better Auth-Guide |
| Supabase Auth | Postgres-Backend mit integrierter Auth | Social Login + supabase-js |
Minimal | Supabase Guide |
| Neon Auth | Neon Postgres mit managed Better Auth | @capgo/capacitor-neon |
Minimal | Neon Plugin Docs |
| Firebase Authentication | Apps, die bereits Firebase nutzen | @capgo/capacitor-firebase-authentication |
Minimal | Firebase Docs |
| Passkeys | Passwortloser Login auf der eigenen Domain | @capgo/capacitor-passkey |
WebAuthn-Server | Passkey-Docs |
| E-Mail und Passwort | Einfache Apps, eigenes Backend | Keines (HTTP) | Hashing, Reset, Rate Limits | Dieser Artikel |
Natives Social Sign-in (Apple, Google, Facebook)
Ein Plugin deckt die drei großen Consumer-Provider sowie eine generische OAuth2-Engine ab:
bun add @capgo/capacitor-social-login
bunx cap sync
import { SocialLogin } from '@capgo/capacitor-social-login';
await SocialLogin.initialize({
apple: { clientId: 'com.example.app' },
google: {
webClientId: 'WEB_CLIENT_ID.apps.googleusercontent.com',
iOSClientId: 'IOS_CLIENT_ID.apps.googleusercontent.com',
},
});
const { result } = await SocialLogin.login({ provider: 'google', options: {} });
// send result.idToken to your server
Deaktiviere Anbieter, die du nicht nutzt, in capacitor.config.ts (plugins.SocialLogin.providers) sodass deren SDKs nicht in die App kompiliert werden. Das entfernt auch die Facebook SDK Advertising ID Permission, falls du Facebook nicht nutzt.
Jeder Provider erfordert ein natives Setup: Apple benötigt die entsprechende Capability in Xcode und Android eine Services ID; Google benötigt SHA-1 Fingerprints und ein reversed Client ID URL Scheme. Die Apple und Google Guides führen dich durch jeden Schritt und erklären häufige Fehler.
Enterprise SSO mit OAuth 2.0 und OpenID Connect
Für Auth0, Okta, Microsoft Entra ID, Keycloak, Cognito, OneLogin oder deinen eigenen OIDC-Server nutzt du den oauth2 Provider des Plugins. Er führt den Authorization code Flow mit PKCE in ASWebAuthenticationSession auf iOS und in Custom Tabs auf Android aus, wenn du androidUseCustomTabs: true:
await SocialLogin.initialize({
oauth2: {
corp: {
issuerUrl: 'https://sso.example.com/realms/mobile', // OIDC discovery
clientId: 'mobile-app',
redirectUrl: 'com.example.app://oauth/corp',
scope: 'openid profile email offline_access',
pkceEnabled: true,
androidUseCustomTabs: true,
},
},
});
const { result } = await SocialLogin.login({
provider: 'oauth2',
options: { providerId: 'corp' },
});
Du kannst mehrere Provider in derselben Map registrieren und einen auswählen mit providerId, wodurch Multi-Tenant B2B-Apps es jedem Kunden ermöglichen, seinen eigenen IdP zu nutzen. Das Plugin kümmert sich auch um das Refresh (SocialLogin.refresh), Logout mit id_token_hint, sowie ein Ionic Auth Connect-kompatibler Wrapper (SocialLoginAuthConnect) für Teams, die von Auth Connect migrieren. Provider-Walkthroughs: Auth0, Okta, Entra ID. Zum Hintergrund des Protokolls siehe 5 Schritte zur Implementierung von OAuth2 in Capacitor Apps.
Gehostete Backends: Firebase, Supabase und Neon
Wenn deine Daten bereits in Firebase, Supabase oder Neon liegen, nutze deren Auth, damit Security Rules und Row-Level Security ohne zusätzlichen Aufwand funktionieren.
- Supabase: Hol dir einen ID-Token mit dem Social Login Plugin und rufe
supabase.auth.signInWithIdToken({ provider: 'google', token }). Supabase verifiziert dies und gibt eine Session zurück. Komplette Einrichtung: Supabase mit Capacitor Social Login. - Neon: Neon Auth ist ein verwaltetes Better Auth, das auf deinem Neon-Branch läuft.
@capgo/capacitor-neonmeldet Nutzer nativ mit E-Mail und Passwort, E-Mail-OTP, Google, GitHub oder Vercel OAuth im Systembrowser an. Es liefert ein JWT für den Neon Data API, sodass Row-Level Security greift. Komplette Einrichtung: Neon Plugin-Docs. - Firebase: Nutze entweder
@capgo/capacitor-firebase-authentication, welches die nativen Firebase Auth SDKs kapselt, oder erhalte einen ID-Token via Social Login und erstelle daraus eine Firebase-Credential im JS SDK. Siehe Firebase Google Login Dokumentation.
Self-hosted: Better Auth
Better Auth ist eine Open-Source TypeScript Auth-Library, die Nutzer in deiner eigenen Datenbank speichert. In Capacitor funktioniert es, sobald du den App-Origins vertraust und auf Bearer Tokens umsteigst, da Cross-Site-Cookies in der WKWebView unzuverlässig sind. Social Login erfolgt über das native Plugin und einen ID-Token-Handoff. Schritt für Schritt: So nutzt du Better Auth in Capacitor Apps.
Passkeys
Passkeys ersetzen Passwörter durch ein Schlüsselpaar, das im iCloud Keychain oder Google Password Manager gespeichert wird. Dafür muss deine App mit deiner Website-Domain verknüpft sein (apple-app-site-association unter iOS, assetlinks.json auf Android) und einen WebAuthn-Server nutzen.
@capgo/capacitor-passkey ermöglicht die Nutzung von Standard-WebAuthn code. Konfiguriere die Relying Party in capacitor.config.ts, rufe den Shim einmal beim Startup auf, und navigator.credentials.create() und .get() werden an die nativen Passkey-APIs weitergeleitet:
import { CapacitorPasskey } from '@capgo/capacitor-passkey';
await CapacitorPasskey.autoShimWebAuthn();
// existing WebAuthn code keeps working
const assertion = await navigator.credentials.get({
publicKey: requestOptionsFromServer,
});
Libraries wie Better Auth oder Hosted-Provider wie Auth0 und Okta können als WebAuthn-Server fungieren. Siehe die Passkey-Plugin-Seite.
E-Mail und Passwort mit deinem eigenen Backend
Es ist kein Plugin nötig, es ist einfach fetch. Die Arbeit findet auf dem Server statt: Hashen mit Argon2id oder bcrypt, Rate-Limiting für Login-Versuche, Versenden von Verifizierungs- und Reset-E-Mails sowie Unterstützung der Kontolöschung. Öffne Reset- und Verifizierungslinks in der App via Universal Links und App Links, damit der Link auf dem Smartphone an der richtigen Stelle landet. Sofern du keinen Grund hast, das alles selbst zu betreiben, bieten dir Libraries wie Better Auth oder ein Hosted-Service dieselben Features mit weniger Risiko.
Tokens immer auf dem Server verifizieren
Clientseitige Checks lassen sich umgehen. Unabhängig vom Provider muss der Server das Token verifizieren, bevor eine Session erstellt wird:
import { createRemoteJWKSet, jwtVerify } from 'jose';
type IssuerConfig = {
jwks: ReturnType<typeof createRemoteJWKSet>;
issuer: string | string[];
audience: string[];
};
const issuers: Record<'google' | 'apple', IssuerConfig> = {
google: {
jwks: createRemoteJWKSet(new URL('https://www.googleapis.com/oauth2/v3/certs')),
issuer: ['https://accounts.google.com', 'accounts.google.com'],
audience: ['WEB_CLIENT_ID.apps.googleusercontent.com', 'IOS_CLIENT_ID.apps.googleusercontent.com'],
},
apple: {
jwks: createRemoteJWKSet(new URL('https://appleid.apple.com/auth/keys')),
issuer: 'https://appleid.apple.com',
audience: ['com.example.app', 'com.example.app.signin'],
},
};
export async function verifyIdToken(provider: 'google' | 'apple', idToken: string) {
const cfg = issuers[provider];
const { payload } = await jwtVerify(idToken, cfg.jwks, {
issuer: cfg.issuer,
audience: cfg.audience,
});
return payload; // use payload.sub as the stable provider user ID
}
User identifizierst du über die sub des Providers (plus Provider-Name), nicht über die E-Mail. Verknüpfe Konten nur per E-Mail, wenn der Provider sie als verifiziert markiert (email_verified: true). Metas Limited-Login-Tokens enthalten diesen Claim nicht.
Session sicher speichern
localStorage und Capacitor Preferences sind einfache Dateien. Speichere langlebige Tokens im Keychain (iOS) oder im Keystore-verschlüsselten Speicher (Android). @capgo/capacitor-native-biometric bietet einfache setData, getData und deleteData Methoden dafür:
bun add @capgo/capacitor-native-biometric
bunx cap sync
import { NativeBiometric } from '@capgo/capacitor-native-biometric';
export const sessionStore = {
async save(token: string) {
await NativeBiometric.setData({ key: 'session.token', value: token });
},
async load(): Promise<string | null> {
try {
const { value } = await NativeBiometric.getData({ key: 'session.token' });
return value;
} catch {
return null;
}
},
async clear() {
await NativeBiometric.deleteData({ key: 'session.token' }).catch(() => {});
},
};
Halte Access Tokens kurzlebig und erneuere sie per Refresh Token oder Server-Session. Unser Guide zur sicheren Token-Speicherung geht tiefer auf Rotation und Revocation ein.
Biometrie: Entsperren, nicht Identität
Face ID und Fingerabdruck beweisen nur, dass die Person das Handy entsperren kann. Nutze sie, um den Zugriff auf eine Session zu steuern:
import { AccessControl, NativeBiometric } from '@capgo/capacitor-native-biometric';
// after a real login, offer biometric unlock
await NativeBiometric.setData({
key: 'session.refresh',
value: refreshToken,
accessControl: AccessControl.BIOMETRY_ANY,
});
// next app start
const { value } = await NativeBiometric.getSecureData({
key: 'session.refresh',
reason: 'Unlock your account',
});
// exchange `value` with your server for a fresh access token
Mit accessControl set, gibt den Wert erst nach erfolgreichem Biometrie-Check frei. Der Schutz wird also durch Keychain oder Keystore erzwungen, nicht durch JavaScript. Kombiniere dies mit serverseitigem Session-Expiry und bei High-Risk-Apps mit Root- und Jailbreak-Detection. Mehr dazu in Biometrische Authentifizierung in Capacitor Apps.
Eine Methode wählen
| Wenn du … | Nutzt |
|---|---|
| Eine Consumer-App für iOS und Android veröffentlichen | Apple + Google via Social Login, plus E-Mail oder Passkeys |
| An Unternehmen verkaufen, die Microsoft 365 nutzen | Entra ID via OAuth2-Provider |
| Viele Enterprise-IdPs pro Kunde benötigen | Auth0 oder Okta als Broker, oder mehrere OAuth2-Provider providerId |
| Bereits Supabase oder Firebase nutzen | Deren Auth mit nativem ID-Token-Sign-in |
| Bereits Neon nutzen | Neon Auth über @capgo/capacitor-neon |
| Eigene Benutzertabelle ohne Drittanbieter erstellen | Better Auth |
| Passwortloses Login gewünscht? | Passkeys, mit Fallback wie Magic Links per E-Mail |
| Schneller Re-Login gewünscht? | Biometrisches Entsperren einer gespeicherten Session zusätzlich zu den oben genannten Optionen |
App-Store- und Play-Store-Regeln für Logins
- Apple 4.8 Login Services: Da ein Drittanbieter-Login als primäres Kontosystem eine gleichwertige, datenschutzorientierte Option erfordert, ist Sign in with Apple die ideale Lösung.
- Apple 5.1.1(v): Account-Erstellung erfordert eine Account-Löschung in der App, und Sign in with Apple Tokens sollten widerrufen werden. Siehe Compliance bei der Account-Löschung.
- Google Play-Kontolöschung: Apps mit Konten müssen die Löschung in der App und über einen in der Play Console angegebenen Web-Link anbieten.
- Reviewer-Zugriff: give reviewers a working demo account. If login is SSO only, provide a test tenant user.
- Xcode 26: App Store Connect erfordert seit April 2026 Builds mit Xcode 26 und dem iOS 26 SDK. Aktualisieren Sie daher alles, bevor Sie ein Release mit neuen Auth-Funktionen einreichen.
Auth-Änderungen sicher deployen
Auth bugs block every user, so you want to fix them fast. Native changes (entitlements, URL schemes, intent filters) need a store build. Everything in TypeScript, like provider config, scopes, error handling and UI, can be pushed with Capgo Live Updates und im Fehlerfall sofort zurückgerollt werden. Capgo Build erstellt die signierten iOS- und Android-Binaries in der Cloud, sobald ein neues Native Build benötigt wird.
Nächste Schritte
Wähle deinen Provider und folge dem passenden Guide: