Zum Hauptinhalt springen

Wie man bessere Auth in Capacitor-Apps verwendet (2026-Leitfaden)

Bessere Auth in einer Capacitor-App verwenden: Vertrauenswürdige Ursprünge, Bearer-Tokens anstelle von Cookies, E-Mail- und Passwort, native Google- und Apple-Anmeldung und Korrekturen.

Artikelcredits

Martin Donadieu

Autor

Valeria

Rezensent

Jordan

Redakteur

Wie man Bessere Auth in Capacitor-Apps verwendet (2026-Leitfaden)

Um Better Auth in einer Capacitor-App zu verwenden, installieren Sie better-auth client in Ihrem Web code, verweisen Sie es auf Ihren Better Auth-Server, fügen Sie die Capacitor Ursprünge hinzu ("capacitor://localhost auf iOS, https://localhost auf Android) zu trustedOrigins, und wechseln Sie von Cookies zu Bearer-Tokens mit dem bearer Plugin. E-Mail- und Passwort funktionieren über den SDK unverändert. Für Google und Apple erhalten Sie einen ID-Token mit einem nativen Plugin wie @capgo/capacitor-social-login und übergeben Sie es an authClient.signIn.social({ idToken }).

Diese Anleitung zeigt die Server- und Client-Konfiguration, die Token-Speicherung, den sozialen Anmeldevorgang, die Unterstützung von Enterprise-Anbietern und die Fehler, die Menschen erleben, wenn sie eine bessere Authentifizierung im Web in Capacitor 8 umsetzen.

Was ändert sich, wenn bessere Authentifizierung innerhalb von Capacitor

Ein Capacitor-App ist eine Web-App, die von einem lokalen Ursprung innerhalb eines nativen WebView ausgeliefert wird. Im Vergleich zu einer normalen Website sind drei Dinge anders:

Thema Auf einer Website In einer Capacitor-App
Ursprung https://app.example.com capacitor://localhost (iOS), https://localhost (Android)
Auth-Server Oftmals funktionieren Cookies auf derselben Seite Verschiedene Domäne, Drittanbieter-Cookies werden durch WKWebView blockiert
OAuth-Redirects Ein vollständiger Seiten-Redirect ist in Ordnung Der Redirect verlässt Ihre gebündelte App, Google blockiert WebViews

Die Lösungen sind: Vertrauen Sie den Capacitor Ursprüngen, verwenden Sie Bearer-Tokens und verwenden Sie native Plugins für soziale Anmeldungen

Schritt 1: Konfigurieren Sie den Better Auth-Server

Diese Beispiele verwenden Hono, aber die Better Auth-Konfiguration ist für Express, Next.js Routen-Handler oder jede andere Laufzeit gleich

bun add better-auth hono
// auth.ts
import { betterAuth } from 'better-auth';
import { bearer } from 'better-auth/plugins';
import { db } from './db'; // your Drizzle, Prisma, Kysely or pg instance

export const auth = betterAuth({
  baseURL: process.env.BETTER_AUTH_URL, // https://auth.example.com
  database: db,
  emailAndPassword: {
    enabled: true,
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_WEB_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
    apple: {
      clientId: process.env.APPLE_SERVICE_ID as string,
      clientSecret: process.env.APPLE_CLIENT_SECRET as string,
      appBundleIdentifier: process.env.APPLE_BUNDLE_ID as string, // com.example.app
    },
  },
  trustedOrigins: [
    'capacitor://localhost', // iOS WebView
    'https://localhost', // Android WebView (androidScheme https, the default)
    'https://app.example.com', // your web build
    'https://appleid.apple.com',
  ],
  plugins: [bearer()],
});

appBundleIdentifier macht für Apple. Token von der native iOS-Schaltfläche tragen Ihre Bundle-ID als Zielgruppe, während Web- und Android-Token die Services-ID tragen. Better Auth verwendet diesen Feld, um beide anzunehmen

Montieren Sie den Handler und erlauben Sie CORS von den App-Ursprüngen. Expose die set-auth-token Überschrift, andernfalls sieht der Client den Bearer-Token nie:

// server.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { auth } from './auth';

const app = new Hono();

app.use(
  '/api/auth/*',
  cors({
    origin: ['capacitor://localhost', 'https://localhost', 'https://app.example.com'],
    allowHeaders: ['Content-Type', 'Authorization'],
    allowMethods: ['GET', 'POST', 'OPTIONS'],
    exposeHeaders: ['set-auth-token'],
    credentials: true,
  }),
);

app.on(['GET', 'POST'], '/api/auth/*', (c) => auth.handler(c.req.raw));

export default app;

Starten bunx @better-auth/cli migrate (or generate für Ihre ORM) um die Tabellen zu erstellen.

Schritt 2: Erstellen Sie den Auth-Kunden in der App

bun add better-auth @capgo/capacitor-native-biometric
bunx cap sync

Speichern Sie den Sitzungstoken im Keychain oder Keystore und halten Sie eine Kopie im Speicher, damit der Client es synchron lesen kann.

// auth-client.ts
import { createAuthClient } from 'better-auth/client';
import { NativeBiometric } from '@capgo/capacitor-native-biometric';

const TOKEN_KEY = 'session.token';
let sessionToken = '';

export async function loadSessionToken() {
  try {
    const { value } = await NativeBiometric.getData({ key: TOKEN_KEY });
    sessionToken = value;
  } catch {
    sessionToken = '';
  }
}

async function saveSessionToken(token: string) {
  sessionToken = token;
  if (token) {
    await NativeBiometric.setData({ key: TOKEN_KEY, value: token });
  } else {
    await NativeBiometric.deleteData({ key: TOKEN_KEY }).catch(() => {});
  }
}

export const authClient = createAuthClient({
  baseURL: 'https://auth.example.com',
  fetchOptions: {
    auth: {
      type: 'Bearer',
      token: () => sessionToken,
    },
    onSuccess: async (ctx) => {
      const token = ctx.response.headers.get('set-auth-token');
      if (token) await saveSessionToken(token);
    },
  },
});

export async function clearSession() {
  await saveSessionToken('');
}

Call await loadSessionToken() vor dem Rendern Ihrer App authClient.getSession() aus dem entsprechenden Unterpfad (

import { authClient, loadSessionToken } from './auth-client';

await loadSessionToken();
const { data: session } = await authClient.getSession();
if (session) {
  console.log('Signed in as', session.user.email);
}

Wenn Sie React, Vue, Svelte oder Solid verwenden, importieren Sie createAuthClient aus der entsprechenden Unterpfad ("better-auth/react, better-auth/vue, …) um die useSession Hook. Das fetchOptions bleiben gleich. Das setData und getData methods are native only. On web, fall back to cookies or sessionStorage mit Capacitor.isNativePlatform().

Schritt 3: E-Mail und Passwort

Kein Plugin erforderlich. Dies sind einfache HTTP-Anfragen.

import { authClient, clearSession } from './auth-client';

export async function signUp(email: string, password: string, name: string) {
  const { data, error } = await authClient.signUp.email({ email, password, name });
  if (error) throw new Error(error.message);
  return data;
}

export async function signIn(email: string, password: string) {
  const { data, error } = await authClient.signIn.email({ email, password });
  if (error) throw new Error(error.message);
  return data;
}

export async function signOut() {
  await authClient.signOut();
  await clearSession();
}

Für E-Mail-Verifizierung und Passwort-Restart sendet Better Auth Links, die eine URL öffnen. Klicken Sie callbackURL at a page on your domain that is also configured as an iOS Universal Link and Android App Link, so the link opens the app on phones and the website elsewhere.

Konfigurieren Sie Google wie in

"Wie Sie sich mit Google anmelden" unter __CAPGO_KEEP_0__ "Wie Sie sich mit Google anmelden" unter Capacitor, dann:

import { SocialLogin } from '@capgo/capacitor-social-login';
import { authClient } from './auth-client';

await SocialLogin.initialize({
  google: {
    webClientId: 'WEB_CLIENT_ID.apps.googleusercontent.com',
    iOSClientId: 'IOS_CLIENT_ID.apps.googleusercontent.com',
    mode: 'online', // Better Auth needs the idToken, offline mode only returns a code
  },
});

export async function signInWithGoogle() {
  const { result } = await SocialLogin.login({ provider: 'google', options: {} });

  if (result.responseType !== 'online' || !result.idToken) {
    throw new Error('Google did not return an ID token');
  }

  const { data, error } = await authClient.signIn.social({
    provider: 'google',
    idToken: {
      token: result.idToken,
      accessToken: result.accessToken?.token,
    },
  });
  if (error) throw new Error(error.message);
  return data;
}

Better Auth überprüft den Token gegen die Schlüssel von Google und den konfigurierten Client-Id, erstellt oder verknüpft den Benutzer und gibt eine Sitzung zurück. Der Bearer-Token landet im set-auth-token Header und Ihr onSuccess Hook speichert ihn.

Schritt 5: Native Apple-Authentifizierung

Konfigurieren Sie Apple wie in How to sign in with Apple using Capacitor. Generieren Sie einen Zufallswert, übermitteln Sie ihn an Apple und senden Sie denselben Wert an Better Auth:

import { SocialLogin } from '@capgo/capacitor-social-login';
import { authClient } from './auth-client';

export async function signInWithApple() {
  const nonce = crypto.randomUUID();

  const { result } = await SocialLogin.login({
    provider: 'apple',
    options: { scopes: ['email', 'name'], nonce },
  });

  if (!result.idToken) throw new Error('Apple did not return an ID token');

  const { data, error } = await authClient.signIn.social({
    provider: 'apple',
    idToken: {
      token: result.idToken,
      nonce,
      accessToken: result.accessToken?.token,
    },
  });
  if (error) throw new Error(error.message);
  return data;
}

Apple teilt den Benutzernamen nur auf der ersten Autorisierung mit. Wenn Sie ihn auf dem Benutzerkonto haben möchten, aktualisieren Sie das Profil direkt nach der ersten Anmeldung mit result.profile.givenName und familyName.

Facebook folgt dem gleichen Muster. Auf iOS mit Limited Login erhalten Sie ein idTokensonst müssen Sie den Zugriffstoken übermitteln. Bessere Auth-Integration Seite besitzt die vollständige Facebook-Beispielanwendung.

Schritt 6: Okta, Auth0, Entra ID und andere OIDC-Anbieter

Bessere Auths genericOAuth Plugin liefert Hilfsmittel für Auth0, Okta, Keycloak und Microsoft Entra ID, sowie eine manuelle Konfiguration für jeden OIDC-Server. Im Web-Builder authClient.signIn.oauth2({ providerId }) funktioniert es wie auf jeder Website.

Auf iOS und Android benötigt der Flow den Systembrowser, da die Anbieter-Login-Seite nicht innerhalb Ihres WebView laden darf. Der funktionierende Muster lautet:

  1. Die App öffnet Ihre Better Auth-Anmeldeseite im Systembrowser (z.B. SocialLogin.openSecureWindow oder einem in-app-Browser-Plugin).
  2. Bessere Auth führt den OAuth-Tanz mit dem Anbieter durch und erstellt die Sitzung auf dem Server.
  3. Ihre Callback-Seite wandelt diese Sitzung in einen kurzlebigen, einmaligen Token um (Bessere Auth verfügt über ein oneTimeToken Plugin für diese Funktion) und leitet zu einer tiefen Verlinkung wie com.example.app://auth?token=....
  4. Die App überprüft den einmaligen Token mit dem Auth-Client und erhält eine normale Bearer-Sitzung.

Das ist mehr Komponenten als der ID-Token-Übertrag. Wenn Sie nur Enterprise SSO benötigen und keine Benutzerdatenbank von Better Auth benötigen, ist das direkte Anmelden gegenüber dem Provider einfacher, siehe die Okta, Auth0 und Benutzerkennung Anleitungen.

Schritt 7: Schützen Sie Ihr API mit der Sitzung

Ihr eigener API kann die Sitzung aus dem Bearer-Token lesen, mit dem Server von Better Auth: API.

import { Hono } from 'hono';
import { auth } from './auth';

const api = new Hono();

api.get('/me/orders', async (c) => {
  const session = await auth.api.getSession({ headers: c.req.raw.headers });
  if (!session) return c.json({ error: 'unauthorized' }, 401);
  return c.json(await listOrders(session.user.id));
});

Der Bearer-Plugin macht getSession accept Authorization: Bearer <token> wie es den Cookie annimmt.

Troubleshooting

Problem Ursache Lösung
Invalid origin oder 403 bei der Anmeldung Capacitor Ursprung nicht vertraut Hinzufügen capacitor://localhost und https://localhost zu trustedOrigins
CORS-Fehler im WebView-Konsolenfenster Der Server CORS listet die App-Ursprünge nicht auf Hinzufügen sie zu Ihrem CORS-Middleware, zulassen Authorization
Anmeldung erfolgreich, aber getSession keine null Übertragung von Cookies zwischen Domains Verwenden Sie den Bearer-Plugin und senden Sie den Token
set-auth-token ist immer null Header nicht sichtbar Hinzufügen exposeHeaders: ['set-auth-token'] CORS
Google: disallowed_useragent Authentifizierungsbildschirm in der WebView Verwenden Sie native Authentifizierung und die idToken Übertragung
Google-ID-Token abgelehnt Audience passt nicht zum konfigurierten Client-ID Entschlüsseln Sie den Token mit SocialLogin.decodeIdToken und vergleichen Sie aud mit clientId
Apple-ID-Token abgelehnt auf iOS Audience ist die Bundle-ID Setzen Sie appBundleIdentifier im Apple-Anbieter
In der Apple-Anbieter Verschiedene Nichtwiederholbarkeitswerte an Apple und Better Auth Wert einmal generieren, wiederholen Sie ihn
Nach der App-Neustart verloren Token nur im Speicher Persistiere mit setData und laden Sie es vor der ersten Anfrage

Die Mobilseite bereitstellen

Auth-Änderungen sind selten native. Vertrauenswürdige Ursprünge und Anbieter sind Serverkonfiguration, und der Client code ist TypeScript, daher können die meisten Fixes über code Live-Updates verschickt werden Capgo Live-Updates anstatt einer Store-Veröffentlichung. Sie benötigen nur eine neue Binärdatei, wenn Sie ein natives Plugin hinzufügen oder die URL-Schemas ändern.

Live Updates für Capacitor-Apps

Wenn ein Web-Schicht-Bug live ist, schicken Sie die Reparatur über Capgo anstatt Tage für die Genehmigung durch den App-Store zu warten. Die Benutzer erhalten die Aktualisierung im Hintergrund, während native Änderungen im normalen Review-Prozess bleiben.

Neueste von unserem Blog

Capgo gibt Ihnen die besten Einblicke, die Sie benötigen, um ein wirklich professionelles Mobiltelefon-App zu erstellen.