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 :
- L'application génère un vérificateur et un défi PKCE, puis ouvre
https://YOUR_TENANT/authorizedans un navigateur sécurisé. - L'utilisateur se connecte (mot de passe, social, passkey, MFA, tout ce que vous avez configuré dans Auth0).
- Auth0 redirige vers votre URL de callback avec un
code. - L'application échange le code et le vérificateur PKCE sur
/oauth/tokenpour 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
- Dans le Dashboard Auth0, allez à Applications > Applications > Créer une application.
- Choisissez Natif et créez-la.
- Dans l'onglet Paramètres onglet, notez le Domaine (par exemple
example.eu.auth0.com) et le ID client. - 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 :
- Dans Paramètres > Rotation du refresh token, activez la rotation. Chaque refresh renvoie un nouveau refresh token et invalide l’ancien.
- Définissez une durée de vie absolue et d’inactivité adaptée à votre produit.
- Si vous appelez votre propre API, ouvrez Applications > API > votre API > Paramètres et activez Autoriser l’accès hors ligne.
- Demandez le
offline_accessscope 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.