Saltare al contenuto principale

Come utilizzare l'autenticazione migliore nei Capacitor (Guida 2026)

Usa l'autenticazione migliore in un'app Capacitor: origini fidate, token di accesso al posto di cookie, email e password, accesso nativo di Google e Apple e correzioni.

Come usare l'autenticazione migliore nelle app Capacitor (Guida 2026)

Per usare Better Auth in un'app Capacitor, installa il better-auth client nel tuo web code, puntalo sul tuo server Better Auth, aggiungi gli Capacitor origini (capacitor://localhost su iOS, https://localhost On Android) per trustedOrigins, e passa dai cookie ai token bearer con il bearer plugin. Email e password funziona attraverso il SDK così com'è. Per Google e Apple, ottieni un token ID con un plugin nativo come @capgo/capacitor-social-login e passalo a authClient.signIn.social({ idToken }).

Questa guida mostra la configurazione del server e del client, lo storage dei token, l'accesso con account social, i provider aziendali e gli errori che le persone incontrano quando spostano un'app web Better Auth in Capacitor 8.

Cosa cambia quando Better Auth funziona all'interno di Capacitor

Un'app Capacitor è un'app web servita da un origin locale all'interno di un WebView nativo. Rispetto a un normale sito web, tre cose sono diverse:

Argomento Sul sito web In un'app Capacitor
Origine https://app.example.com capacitor://localhost (iOS), https://localhost (Android)
Auth server Spesso lo stesso sito, i cookie funzionano comunque Diverso dominio, i cookie di terze parti vengono bloccati da WKWebView
I redirect OAuth Un redirect a pagina completa è accettabile Il redirect lascia il tuo'applicazione bundle, Google blocca i WebViews

Le soluzioni sono: fidarsi degli origini Capacitor, utilizzare token bearer e utilizzare plugin nativi per il login sociale

Passo 1: Configura il server di autenticazione Better Auth

Questa esempio utilizza Hono, ma la configurazione di Better Auth è la stessa per Express, gestori di route Next.js o qualsiasi altro runtime

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 Importa per Apple. I token dal foglio di iOS nativo portano il tuo ID bundle come destinatario, mentre i token web e Android portano l'ID Servizi. Better Auth utilizza questo campo per accettare entrambi

Monta il gestore e consenti CORS dai origini dell'applicazione. Espone il set-auth-token header, altrimenti il client non vede mai il token di autenticazione bearer:

// 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;

Run bunx @better-auth/cli migrate (or generate Step 2: Crea il client di autenticazione nell'app

Passo 2: Crea il client di autenticazione nell'app

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

Memorizza il token di sessione nel Keychain o Keystore e conserva una copia in memoria affinché il client possa leggerlo in modo sincrono.

// 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() per ripristinare l'utente: authClient.getSession() per ripristinare l'utente:

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

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

Se utilizzi React, Vue, Svelte o Solid, importa createAuthClient , …) per ottenere ilbetter-auth/react, better-auth/vuePer ottenere i risultati migliori useSession hook. Il fetchOptions stay the same. Lo stesso. Il setData e getData metodi sono nativi solo. Sul web, ricadono su cookie o sessionStorage utilizzando Capacitor.isNativePlatform().

Step 3: Email e password

Nessun plugin necessario. Si tratta di chiamate HTTP semplici.

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();
}

Non è necessario alcun plugin. Questi sono semplici chiamate HTTP. callbackURL Per la verifica dell'indirizzo email e il reset della password, Better Auth invia link che aprono una URL. Indicizza

Passo 4: accesso con Google

Step 4: Accesso Google nativo context: How to sign in with Google using Capacitorpoi, quindi:

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;
}

Miglior Autenticazione verifica il token contro le chiavi di Google e l'ID del client configurato, crea o collega l'utente e restituisce una sessione. Il token di accesso arriva nel set-auth-token header e il tuo onSuccess hook lo memorizza.

Passo 5: Accesso nativo Apple

Configura Apple come descritto in Come effettuare l'accesso con Apple utilizzando Capacitor. Genera un valore nonce, passalo ad Apple e invia lo stesso valore a Miglior Autenticazione:

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 condivide solo il nome dell'utente alla prima autorizzazione. Se desideri che sia presente nel record utente, aggiorna il profilo subito dopo il primo accesso con result.profile.givenName e familyName.

Facebook segue lo stesso schema. Su iOS con Accesso Limitato ottieni un idTokenaltrove passa il token di accesso. Il Integrazione di Autenticazione Migliorata pagina ha l'esempio completo di Facebook.

Passo 6: Okta, Auth0, Entra ID e altri provider OIDC

Better Auth genericOAuth Il plugin fornisce ausili per Auth0, Okta, Keycloak e Microsoft Entra ID, oltre a una configurazione manuale per qualsiasi server OIDC. Nella build web, authClient.signIn.oauth2({ providerId }) funziona come su qualsiasi sito.

On iOS and Android the flow needs the system browser, because the provider login page must not load inside your WebView. The pattern that works:

  1. L'app apre la tua URL di accesso a Better Auth nel browser del sistema (ad esempio con) SocialLogin.openSecureWindow o un plugin del browser integrato nell'app.
  2. Autenticazione Migliorata esegue il ballo OAuth con il provider e crea la sessione sul server.
  3. Autenticazione Migliorata esegue il ballo di OAuth con il provider e crea la sessione sul server. oneTimeToken plugin per questo) e reindirizza a un link profondo come com.example.app://auth?token=....
  4. L'App verifica il token a tempo di validità con il client di autenticazione e riceve una sessione bearer normale.

Questo comporta più parti in movimento rispetto alla cessione del token ID. Se hai bisogno solo di SSO aziendale e non hai bisogno della base di dati degli utenti di Better Auth, accedere direttamente al provider è più semplice, vedi i Okta, Auth0 e guida. guides.

Passo 7: Proteggere il tuo API con la sessione

Il tuo API può leggere la sessione dal token di autenticazione con il server API di Better Auth.

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));
});

Il plugin bearer fa getSession accept Authorization: Bearer <token> nella stessa maniera accetta il cookie.

Risolvere i problemi

Problema Causa Soluzione
Invalid origin o 403 all'accesso Capacitor non è stato riconosciuto come origine Aggiungi capacitor://localhost e https://localhost a trustedOrigins
errore CORS nel console WebView Il server CORS non elenca le origini dell'app Aggiungile al tuo middleware CORS, consenti Authorization
Accedi con successo ma getSession ritorna null Risiede su cookie tra domini Utilizza il plugin bearer e invia il token
set-auth-token è sempre null La testata non è esposta Aggiungi exposeHeaders: ['set-auth-token'] utilizzare CORS
Google: disallowed_useragent La pagina di accesso OAuth è caricata nel WebView Utilizza l'accesso nativo e il idToken handoff
Token Google rifiutato L'audience non corrisponde all'ID del client configurato Decodifica il token con SocialLogin.decodeIdToken e confronta aud con clientId
Token ID Apple rifiutato su iOS L'audience è l'ID del bundle Imposta appBundleIdentifier nel fornitore Apple
nel provider Apple Nonce diverso inviato a Apple e Better Auth Nonce diverso inviato ad Apple e Better Auth
La sessione persa dopo il riavvio dell'app Il token viene conservato solo in memoria Persisti con setData e caricalo prima della prima richiesta

La distribuzione del lato mobile

Auth changes are rarely native. Trusted origins and providers are server config, and the client code is TypeScript, so most fixes can ship through Capgo aggiornamenti in tempo reale Invece di una versione di store. Hai bisogno di un nuovo binario solo quando aggiungi un plugin nativo o cambi i schemi di URL.

Aggiornamenti in tempo reale per le app Capacitor

Quando un bug nel layer web è attivo, invia la correzione attraverso Capgo invece di attendere giorni per l'approvazione delle app store. Gli utenti ricevono l'aggiornamento in background mentre le modifiche native rimangono nel normale percorso di revisione.

Ultimi articoli del nostro Blog

Capgo vi dà le migliori informazioni che avete bisogno per creare un'app mobile veramente professionale.