Salta al contenuto principale

Come accedere con Auth0 usando Capacitor

Aggiungi il login Auth0 a un'app Capacitor 8 con OIDC e PKCE: configurazione Auth0 dashboard, callback URL, API audience, refresh token, logout e troubleshooting.

L'Auth0 Universal Login aperto da un'app Capacitor tramite il browser di sistema

Per effettuare il login con Auth0 in un'app Capacitor, crea una Nativo application in Auth0, registra un URL di callback con custom-scheme come com.example.app://oauth/auth0, ed esegui il flusso di autorizzazione OpenID Connect code con PKCE tramite il browser di sistema. Con @capgo/capacitor-social-login quello è un initialize chiamata con i tuoi endpoint Auth0 e un SocialLogin.login({ provider: 'oauth2', options: { providerId: 'auth0' } }).

Questa guida copre le impostazioni della dashboard di Auth0, il client code per iOS, Android e web, gli API access token, i refresh token, il logout e gli errori che potresti incontrare. È aggiornata alla versione Capacitor 8 di ottobre 2026.

Come funziona il flusso Auth0 in Capacitor

Auth0 ospita la pagina di login (Universal Login). La tua app non vedrà mai la password. Il flusso è:

  1. L'app genera un PKCE verifier e un challenge, quindi apre https://YOUR_TENANT/authorize un browser sicuro.
  2. L'utente effettua il login (password, social, passkey, MFA, o qualunque cosa tu abbia configurato in Auth0).
  3. Auth0 reindirizza alla tua callback URL con un codice monouso code.
  4. L'app scambia il code e il PKCE verifier presso /oauth/token per un ID token, un access token e, opzionalmente, un refresh token.

Il browser utilizzato dipende dalla piattaforma:

Piattaforma Browser Gestione callback
iOS ASWebAuthenticationSession Gestita dal sistema, nessuna Info.plist modifica
Android WebView integrata di default, o Chrome Custom Tabs con androidUseCustomTabs: true Custom Tabs richiedono un intent filter
Web Popup (default) o redirect a pagina intera handleRedirectCallback() sulla pagina di ritorno

Su Android, usa Custom Tabs. Condividono i cookie con Chrome, supportano passkey e password manager e seguono lo standard RFC 8252 (OAuth per app native), come richiesto da Auth0.

Passaggio 1: Configura l'applicazione Auth0

  1. Nel Dashboard di Auth0, vai su Applications > Applications > Create Application.
  2. Scegli Nativo e crearlo.
  3. Sul Impostazioni tab, nota il Domain (ad esempio example.eu.auth0.com) e il ID Client.
  4. Sotto Credenziali, verifica che il metodo di autenticazione sia Nessuna. Si tratta dell'impostazione public-client usata con PKCE.

URL di callback e logout

Compila questi campi Impostazioni > Application URIs:

Campo Valore per mobile Valore per web
URL di callback consentiti com.example.app://oauth/auth0 https://app.example.com/auth/callback
URL di logout consentiti com.example.app://oauth/logout https://app.example.com/
Origini web consentite Non necessario https://app.example.com

Separa i valori con la virgola. Usa il tuo Capacitor appId come schema. Uno schema reverse-domain evita collisioni con altre app. Se pubblichi anche una build web, molti team creano una Single Page Application in Auth0, così le impostazioni web e mobile non si sovrappongono.

Refresh token

Se gli utenti devono rimanere autenticati:

  1. In Impostazioni > Refresh Token Rotation, attiva la rotazione. Ogni refresh restituisce un nuovo refresh token e invalida il precedente.
  2. Imposta una durata assoluta e di inattività adatta al tuo prodotto.
  3. Se chiami il tuo API, apri Applications > APIs > il tuo API > Settings e abilita Consenti l'accesso offline.
  4. Richiedi lo offline_access scope nell'app.

audience di API

Se il tuo backend valida i token di accesso Auth0, crea un API in Applicazioni > API con un identificatore come https://api.example.com. Passa quell'identificatore come audience. Senza di esso, l'access token è valido solo per l'Auth0 /userinfo endpoint.

Passaggio 2: Installa e configura il plugin

bun add @capgo/capacitor-social-login
bunx cap sync

Se Auth0 è il tuo unico provider, disabilita gli SDK social inclusi per mantenere il binario leggero:

// capacitor.config.ts
plugins: {
  SocialLogin: {
    providers: { google: false, facebook: false, apple: false, twitter: false },
  },
},

Il motore OAuth2 generico non dipende da quegli SDK.

Android intent filter per Custom Tabs

Aggiungi lo scheme di callback a MainActivity nella android/app/src/main/AndroidManifest.xml:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="com.example.app" android:host="oauth" />
</intent-filter>

Il template Capacitor imposta già android:launchMode="singleTask" su MainActivity, necessario per il redirect. Mantienilo.

Passaggio 3: Inizializza il provider Auth0

import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';

const AUTH0_DOMAIN = 'https://example.eu.auth0.com';
const isWeb = Capacitor.getPlatform() === 'web';

export async function initAuth() {
  await SocialLogin.initialize({
    oauth2: {
      auth0: {
        appId: 'YOUR_AUTH0_CLIENT_ID',
        authorizationBaseUrl: `${AUTH0_DOMAIN}/authorize`,
        accessTokenEndpoint: `${AUTH0_DOMAIN}/oauth/token`,
        resourceUrl: `${AUTH0_DOMAIN}/userinfo`,
        redirectUrl: isWeb
          ? 'https://app.example.com/auth/callback'
          : 'com.example.app://oauth/auth0',
        scope: 'openid profile email offline_access',
        pkceEnabled: true,
        additionalParameters: {
          audience: 'https://api.example.com',
        },
        logoutUrl: `${AUTH0_DOMAIN}/oidc/logout`,
        postLogoutRedirectUrl: isWeb
          ? 'https://app.example.com/'
          : 'com.example.app://oauth/logout',
        androidUseCustomTabs: true,
      },
    },
  });
}

Puoi sostituire gli endpoint espliciti con issuerUrl: AUTH0_DOMAIN. Il plugin legge quindi /.well-known/openid-configuration. I valori espliciti prevalgono su quelli rilevati, utile se usi un dominio custom Auth0.

Se stai passando da Ionic Auth Connect, il plugin esporta anche SocialLoginAuthConnect con un auth0 preset che accetta domain, clientId, redirectUrl e audience. Vedi la Guida alla migrazione da Auth Connect.

Passaggio 4: Effettua il login

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function signInWithAuth0() {
  try {
    const { result } = await SocialLogin.login({
      provider: 'oauth2',
      options: { providerId: 'auth0' },
    });

    return {
      idToken: result.idToken,
      accessToken: result.accessToken?.token,
      expiresAt: result.accessToken?.expires,
      refreshToken: result.refreshToken,
      user: result.resourceData, // JSON from /userinfo
    };
  } catch (error: any) {
    if (error?.code === 'USER_CANCELLED') return null;
    throw error;
  }
}

Opzioni di login utili:

  • prompt: 'login' forza la pagina di login anche se Auth0 ha ancora un cookie di sessione attivo.
  • loginHint: 'user@example.com' precompila l'email.
  • additionalParameters: { connection: 'google-oauth2' } salta l'Universal Login e passa direttamente a una connessione.
  • additionalParameters: { screen_hint: 'signup' } apre la schermata di registrazione.

Callback di redirect web

Sul web, il flusso popup predefinito non richiede nulla di extra. Se usi flow: 'redirect', leggi il risultato sulla callback page:

const result = await SocialLogin.handleRedirectCallback();
if (result?.provider === 'oauth2') {
  console.log(result.result.idToken);
}

handleRedirectCallback is web only and rejects on iOS and Android.

Passaggio 5: Leggi l'ID token e chiama il tuo API

Decodifica l'ID token sul client solo per la visualizzazione:

const { claims } = await SocialLogin.decodeIdToken({ idToken: result.idToken! });
console.log(claims.email, claims.name, claims.sub);

decodeIdToken non controlla la firma. Per qualsiasi aspetto relativo alla sicurezza, invia l'access token al tuo API e validalo lì:

import { createRemoteJWKSet, jwtVerify } from 'jose';

const jwks = createRemoteJWKSet(new URL('https://example.eu.auth0.com/.well-known/jwks.json'));

export async function verifyAuth0AccessToken(token: string) {
  const { payload } = await jwtVerify(token, jwks, {
    issuer: 'https://example.eu.auth0.com/', // Auth0 issuers end with a slash
    audience: 'https://api.example.com',
  });
  return payload; // payload.sub is the Auth0 user ID
}

Passaggio 6: Refresh dell'access token

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function getValidAccessToken() {
  const { isLoggedIn } = await SocialLogin.isLoggedIn({ provider: 'oauth2', providerId: 'auth0' });

  if (!isLoggedIn) {
    // access token expired: try the stored refresh token
    try {
      await SocialLogin.refresh({ provider: 'oauth2', options: { providerId: 'auth0' } });
    } catch {
      // refresh token expired, revoked or already rotated: sign in again
      const loginResult = await signInWithAuth0();
      if (!loginResult) throw new Error('Sign-in cancelled');
    }
  }

  const { accessToken } = await SocialLogin.getAuthorizationCode({
    provider: 'oauth2',
    providerId: 'auth0',
  });
  return accessToken;
}

refresh rifiuta quando il refresh token è scaduto o revocato. Con la rotazione attiva, fallisce anche un refresh token già utilizzato, quindi gestisci sempre il rifiuto reindirizzando l'utente al login.

refresh usa il refresh token salvato dal plugin al login. Se gestisci tu il refresh token, chiama SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'auth0', refreshToken }), che restituisce la risposta completa con il nuovo token. Con la rotazione attiva, salva il nuovo refresh token ogni volta.

Il plugin mantiene una copia del token nello storage privato dell'app. Se la tua revisione di sicurezza richiede Keychain o Keystore, salva il refresh token con NativeBiometric.setData({ key, value }) da @capgo/capacitor-native-biometric e passalo a refreshToken te stesso. Il nostro guida allo storage sicuro dei token confronta le opzioni.

Passaggio 7: Logout

await SocialLogin.logout({ provider: 'oauth2', providerId: 'auth0' });

Il plugin elimina i token salvati e poi apre logoutUrl con id_token_hint e post_logout_redirect_uri quindi Auth0 cancella il suo cookie di sessione. Auth0's /oidc/logout riconosce quei parametri e il target del redirect deve essere elencato in URL di logout consentiti.

Su iOS e Android la pagina di end-session si apre nel browser di sistema, quindi l'utente esce brevemente dall'app. Se vuoi solo un logout locale, ometti logoutUrl e passa prompt: 'login' al prossimo login, in modo che una sessione Auth0 memorizzata non riacceda l'utente automaticamente. Impostazione iosPrefersEphemeralSession: true evita anche la condivisione dei cookie su iOS, rinunciando però al SSO tra le app.

Risoluzione problemi

Errore Causa Soluzione
Callback URL mismatch URL di redirect non presente negli Allowed Callback URLs Copia il valore esatto da code nella dashboard, controlla lo scheme e l'host
Unauthorized o invalid_client a /oauth/token Il tipo di app non è Native o il metodo di auth non è None Imposta come Native e imposta token endpoint auth su None
No refreshToken nel risultato offline_access mancante o API non permette l'accesso offline Aggiungi lo scope, abilita Allow Offline Access e abilita la rotation
L'access token non può essere verificato da API No audience inviato Aggiungi audience nella additionalParameters
L'app non si riapre dopo il login su Android Lo scheme o l'host dell'intent filter non corrispondono redirectUrl Abbina com.example.app e oauth esattamente
OAuth2 provider "auth0" not configured login chiamato prima di initialize o mismatch della chiave Await initialize all'avvio, usa lo stesso providerId
La pagina di logout resta aperta post_logout_redirect_uri non presente negli Allowed Logout URLs Aggiungilo, o usa il logout locale
Errore CORS web durante lo scambio del token Origin non presente negli Allowed Web Origins Aggiungi l'origin web, o usa una SPA per il web

Imposta logsEnabled: true nella configurazione del provider per stampare gli URL generati e i dettagli dello scambio del token durante il debug.

Rilascia fix di auth senza passare dagli store

Modificare gli scope, l'audience o la gestione degli errori è possibile solo in TypeScript. Con Live updates di Capgo puoi distribuire i fix agli utenti lo stesso giorno. Le modifiche native, come un nuovo intent filter, richiedono ancora un nuovo binario, che Build Capgo può essere generato nel cloud.

Live updates per le app Capacitor

Quando un bug nel web-layer è live, rilascia la fix tramite Capgo invece di aspettare giorni l'approvazione degli store. Gli utenti ricevono l'update in background, mentre le modifiche native restano nel normale processo di review.

Ultimi articoli dal blog

Capgo ti offre gli insight migliori che ti servono per creare un'app mobile davvero professionale.