Aller au contenu principal

Comment utiliser Auth0 pour se connecter avec Capacitor

Ajoutez la connexion Auth0 à une application Capacitor 8 avec OIDC et PKCE : configuration du dashboard Auth0, URLs de callback, audience API, refresh tokens, déconnexion et dépannage.

Auth0 Universal Login ouvert depuis une application Capacitor via le navigateur système

Pour vous connecter avec Auth0 dans une application Capacitor, créez une Natif application dans Auth0, enregistrez une URL de callback avec schéma personnalisé telle que com.example.app://oauth/auth0, et exécutez le flux d’autorisation OpenID Connect code avec PKCE via le navigateur système. Avec @capgo/capacitor-social-login c'est un initialize appel avec vos endpoints Auth0 et un SocialLogin.login({ provider: 'oauth2', options: { providerId: 'auth0' } }).

Ce guide couvre les paramètres du dashboard Auth0, le client code pour iOS, Android et web, les access tokens API, les refresh tokens, la déconnexion et les erreurs auxquelles vous serez confronté. Il est rédigé pour Capacitor 8, à compter d'octobre 2026.

Fonctionnement du flux Auth0 dans Capacitor

Auth0 héberge la page de connexion (Universal Login). Votre application ne voit jamais le mot de passe. Le flux est le suivant :

  1. L'application génère un vérificateur et un défi PKCE, puis ouvre https://YOUR_TENANT/authorize dans un navigateur sécurisé.
  2. L'utilisateur se connecte (mot de passe, social, passkey, MFA, tout ce que vous avez configuré dans Auth0).
  3. Auth0 redirige vers votre URL de callback avec un code.
  4. L'application échange le code et le vérificateur PKCE sur /oauth/token pour obtenir un ID token, un access token et, le cas échéant, un refresh token.

Le navigateur utilisé dépend de la plateforme :

Plateforme Navigateur Gestion du callback
iOS ASWebAuthenticationSession Géré par le système, aucun Info.plist changement
Android WebView intégrée par défaut, ou Chrome Custom Tabs avec androidUseCustomTabs: true Les Custom Tabs nécessitent un intent filter
Le Web Popup (par défaut) ou redirection pleine page handleRedirectCallback() sur la page de retour

Sur Android, utilisez Custom Tabs. Ils partagent les cookies avec Chrome, prennent en charge les passkeys et les gestionnaires de mots de passe, et respectent la RFC 8252 (OAuth pour les applications natives), ce qu’attend Auth0.

Étape 1 : Configurer l’application Auth0

  1. Dans le Dashboard Auth0, allez à Applications > Applications > Créer une application.
  2. Choisissez Natif et créez-la.
  3. Dans l'onglet Paramètres onglet, notez le Domaine (par exemple example.eu.auth0.com) et le ID client.
  4. Inférieur à Identifiants, vérifiez que la méthode d’authentification est Aucun. C’est le paramètre public-client utilisé avec PKCE.

URL de callback et de déconnexion

Renseignez ces champs dans Paramètres > Application URIs:

Champ Valeur pour mobile Valeur pour web
URLs de callback autorisées com.example.app://oauth/auth0 https://app.example.com/auth/callback
URL de déconnexion autorisées com.example.app://oauth/logout https://app.example.com/
Origines web autorisées Non requis https://app.example.com

Séparez plusieurs valeurs par des virgules. Utilisez votre Capacitor appId comme schéma. Un schéma de domaine inversé évite les collisions avec d'autres applications. Si vous déployez également une version web, de nombreuses équipes créent une application monopage séparée dans Auth0, afin que les paramètres web et mobile ne se mélangent pas.

Tokens de rafraîchissement

Si les utilisateurs doivent rester connectés :

  1. Dans Paramètres > Rotation du refresh token, activez la rotation. Chaque refresh renvoie un nouveau refresh token et invalide l’ancien.
  2. Définissez une durée de vie absolue et d’inactivité adaptée à votre produit.
  3. Si vous appelez votre propre API, ouvrez Applications > API > votre API > Paramètres et activez Autoriser l’accès hors ligne.
  4. Demandez le offline_access scope dans l'application.

audience API

Si votre backend valide les tokens d'accès Auth0, créez un API sous Applications > API avec un identifiant tel que https://api.example.com. Passez cet identifiant comme audience. Sans cela, le token d’accès n’est valable que pour l’endpoint d’Auth0 /userinfo endpoint.

Étape 2 : Installer et configurer le plugin

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

Si Auth0 est votre seul fournisseur, désactivez les SDK sociaux intégrés pour garder un binaire léger :

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

Le moteur OAuth2 générique ne dépend pas de ces SDK.

Filtre d'intent Android pour Custom Tabs

Ajoutez le schéma de callback à MainActivity dans 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>

Le modèle Capacitor définit déjà android:launchMode="singleTask" sur MainActivity, dont la redirection a besoin. Conservez-le.

Étape 3 : initialiser le fournisseur 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,
      },
    },
  });
}

Vous pouvez remplacer les endpoints explicites par issuerUrl: AUTH0_DOMAIN. Le plugin lit ensuite /.well-known/openid-configuration. Les valeurs explicites priment sur celles détectées, ce qui est utile si vous utilisez un domaine personnalisé Auth0.

Si vous migrez depuis Ionic Auth Connect, le plugin exporte également SocialLoginAuthConnect avec un auth0 preset qui prend domain, clientId, redirectUrl et audience. Consultez la Guide de migration Auth Connect.

Étape 4 : Connexion

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

Options de connexion utiles :

  • prompt: 'login' force l’affichage de la page de connexion, même si Auth0 conserve un cookie de session.
  • loginHint: 'user@example.com' pré-remplit l’e-mail.
  • additionalParameters: { connection: 'google-oauth2' } passe outre Universal Login et accède directement à une connexion.
  • additionalParameters: { screen_hint: 'signup' } ouvre l’écran d’inscription.

Callback de redirection web

Sur le web, le flux popup par défaut ne nécessite rien de plus. Si vous utilisez flow: 'redirect', lisez le résultat sur la page de callback :

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

handleRedirectCallback est réservé au web et est rejeté sur iOS et Android.

Étape 5 : Lire le token ID et appeler votre API

Décodez le token ID côté client uniquement pour l’affichage :

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

decodeIdToken ne vérifie pas la signature. Pour tout ce qui concerne la sécurité, envoyez le token d’accès à votre API et validez-le là-bas :

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
}

Étape 6 : Rafraîchir le token d’accès

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 rejette si le token de rafraîchissement est expiré ou révoqué. Avec la rotation activée, un token de rafraîchissement déjà utilisé échoue également. Gérez donc toujours le rejet en renvoyant l’utilisateur vers l’écran de connexion.

refresh utilise le refresh token que le plugin a enregistré lors de la connexion. Si vous gérez vous-même le refresh token, appelez SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'auth0', refreshToken }), qui renvoie la réponse complète du nouveau token. Avec la rotation activée, enregistrez le nouveau refresh token à chaque fois.

Le plugin conserve sa copie du token dans le stockage privé de l’app. Si votre revue de sécurité exige Keychain ou Keystore, stockez le refresh token avec NativeBiometric.setData({ key, value }) depuis @capgo/capacitor-native-biometric et passez-l’à refreshToken vous-même. Notre guide sur le stockage sécurisé des tokens compare les options.

Étape 7 : Se déconnecter

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

Le plugin supprime les tokens stockés, puis ouvre logoutUrl par id_token_hint et post_logout_redirect_uri afin qu'Auth0 efface son cookie de session. L'endpoint d'Auth0 /oidc/logout comprend ces paramètres, et l'URL de redirection cible doit figurer dans URL de déconnexion autorisées.

Sur iOS et Android, la page de fin de session s'ouvre dans le navigateur système : l'utilisateur quitte brièvement l'application. Si vous voulez seulement une déconnexion locale, omettez logoutUrl et passez prompt: 'login' lors de la prochaine connexion pour qu'une session Auth0 mémorisée ne reconnecte pas directement l'utilisateur. Configurer iosPrefersEphemeralSession: true évite également le partage de cookies sur iOS, au prix de l'absence de SSO entre les applications.

Troubleshooting

Erreur Cause Corriger
Callback URL mismatch URL de redirection absente des URL de rappel autorisées Copiez la valeur exacte de code dans le dashboard, vérifiez le schéma et l'hôte
Unauthorized ou invalid_client sur /oauth/token App type is not Native, or auth method is not None Recréez en Native, réglez l'auth du token endpoint sur None
Non refreshToken dans le résultat offline_access manquant ou API n'autorise pas l'accès hors ligne Ajoutez le scope, activez Allow Offline Access et la rotation
Le token d'accès ne peut pas être vérifié par API Non audience envoyé Ajoutez audience dans additionalParameters
L'app ne se rouvre pas après la connexion sur Android Le schéma ou l'hôte du intent filter ne correspond pas redirectUrl Match com.example.app et oauth exactement
OAuth2 provider "auth0" not configured login appelé avant initialize ou clé non correspondante Await initialize au démarrage, utilisez le même providerId
La page de déconnexion reste ouverte post_logout_redirect_uri non présent dans les Allowed Logout URLs Ajoutez-la, ou utilisez une déconnexion locale uniquement
Erreur CORS web lors de l'échange de token Origine non présente dans les Allowed Web Origins Ajoutez l'origine web, ou utilisez une application SPA pour le web

Définissez logsEnabled: true dans la config du provider pour afficher les URLs générées et les détails de l'échange de token pendant votre debug.

Ship auth fixes without a store release

Modifier les scopes, l'audience ou la gestion des erreurs se fait uniquement en TypeScript. Avec les live updates Capgo vous pouvez déployer ces correctifs auprès des utilisateurs le jour même. Les changements natifs comme un nouvel intent filter nécessitent toujours un nouveau binaire, ce qui Build Capgo peut produire dans le cloud.

Live updates pour les apps Capacitor

Lorsqu'un bug de la couche web est en ligne, déployez le correctif via Capgo au lieu d'attendre des jours l'approbation des stores. Les utilisateurs reçoivent la mise à jour en arrière-plan, tandis que les changements natifs suivent le circuit de validation habituel.

Les derniers articles du blog

Capgo vous offre les meilleures informations pour créer une application mobile vraiment professionnelle.