> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Ajouter la fonctionnalité de connexion à votre application Expo

> Ce guide explique comment intégrer Auth0 à n’importe quelle application Expo à l’aide du SDK Auth0 pour React Native.

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Tip>
  Ce Quickstart s’adresse aux applications Expo. Pour intégrer l’authentification Auth0 à votre application React Native, consultez le [Quickstart React Native](https://auth0.com/docs/quickstart/native/react-native/interactive).
</Tip>

<Accordion title="Utiliser l’IA pour intégrer Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si vous utilisez un assistant IA de programmation comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification Auth0 en quelques minutes à l’aide des [agent skills](https://agentskills.io/home).

  **Installer :**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0
  ```

  **Ensuite, demandez à votre assistant IA :**

  ```text theme={null}
  Add Auth0 authentication to my Expo app
  ```

  Votre assistant IA créera automatiquement votre application Auth0, récupérera les identifiants, installera le SDK react-native-auth0, configurera le plugin Expo et mettra en place les flux de connexion et de déconnexion. [Documentation complète sur les agent skills →](/docs/fr-ca/quickstart/agent-skills)
</Accordion>

<div id="get-started">
  ## Commencer
</div>

<Steps>
  <Step title="Créer un nouveau projet Expo" stepNumber={1}>
    Créez un nouveau projet Expo dans le cadre de ce Quickstart.

    **Dans votre terminal :**

    ```bash theme={null}
    npx create-expo-app Auth0ExpoSample --template blank
    cd Auth0ExpoSample
    ```

    <Tip>
      Cela crée une application Expo minimale avec la dernière version du SDK, prête pour l’intégration de modules natifs. L’option `--template blank` fournit un point de départ simple, sans code standard supplémentaire.
    </Tip>

    <Warning>
      Ce SDK n’est **PAS compatible avec Expo Go** parce qu’il nécessite du code natif personnalisé. Vous devez utiliser `npx expo run:ios` ou `npx expo run:android` pour créer une version de développement.
    </Warning>
  </Step>

  <Step title="Installer le SDK d’Auth0" stepNumber={2}>
    Ajoutez le SDK React Native d’Auth0 à votre projet.

    ```bash theme={null}
    npx expo install react-native-auth0
    ```

    <Tip>
      Utiliser `npx expo install` garantit la compatibilité avec votre version du SDK Expo. Le SDK se configure automatiquement grâce au système de plugins Expo.
    </Tip>
  </Step>

  <Step title="Configurer le plugin Expo" stepNumber={3}>
    Configurez le plugin Auth0 pour gérer automatiquement la configuration native d’iOS et d’Android.

    Mettez à jour votre `app.json` pour inclure le plugin Auth0 :

    ```json app.json lines theme={null}
    {
      "expo": {
        "name": "Auth0ExpoSample",
        "slug": "auth0-expo-sample",
        "version": "1.0.0",
        "ios": {
          "bundleIdentifier": "com.auth0.samples.expo",
          "supportsTablet": true
        },
        "android": {
          "package": "com.auth0.samples.expo",
          "adaptiveIcon": {
            "foregroundImage": "./assets/images/adaptive-icon.png",
            "backgroundColor": "#ffffff"
          }
        },
        "plugins": [
          [
            "react-native-auth0",
            {
              "domain": "{yourDomain}",
              "customScheme": "auth0sample"
            }
          ]
        ]
      }
    }
    ```

    Remplacez `{yourDomain}` par votre domaine Auth0 (vous l’obtiendrez à l’étape suivante).

    <Warning>
      **Important** : Vous devez définir `bundleIdentifier` pour iOS et `package` pour Android dans votre fichier `app.json`. Ces identifiants sont nécessaires pour que le SDK Auth0 configure correctement les projets natifs. Si vous ne précisez pas de schéma personnalisé, le SDK utilisera l’identifiant du bundle comme schéma d’URL.
    </Warning>

    <Info>
      Le `customScheme` doit être en minuscules et ne contenir aucun caractère spécial. Cette valeur sert à construire les URL de rappel et doit être transmise aux méthodes `authorize()` et `clearSession()`.
    </Info>
  </Step>

  <Step title="Configurer votre application Auth0" stepNumber={4}>
    Créez et configurez une application Auth0 pour qu’elle fonctionne avec votre application Expo.

    1. Accédez au [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
    2. Cliquez sur **Applications** > **Applications** > **Create Application**
    3. Dans la fenêtre contextuelle, entrez un nom pour votre application (p. ex., `Auth0 Expo Sample`), sélectionnez `Native` comme type d’application, puis cliquez sur **Create**
    4. Ouvrez l’onglet **Settings** dans la page de détails de l’application
    5. Prenez en note les valeurs **Domain** et **Client ID**
    6. Mettez à jour la valeur `domain` dans la Configuration du Plugin de votre `app.json` avec votre domaine Auth0

    **Allowed Callback URLs:**

    ```
    auth0sample://{yourDomain}/ios/com.auth0.samples.expo/callback,
    auth0sample://{yourDomain}/android/com.auth0.samples.expo/callback
    ```

    **URL de déconnexion autorisées :**

    ```
    auth0sample://{yourDomain}/ios/com.auth0.samples.expo/callback,
    auth0sample://{yourDomain}/android/com.auth0.samples.expo/callback
    ```

    Remplacez `{yourDomain}` par votre véritable domaine Auth0 (par ex., `dev-abc123.us.auth0.com`).

    <Info>
      Les **Allowed Callback URLs** constituent une mesure de sécurité essentielle pour s’assurer que les utilisateurs sont redirigés de façon sécuritaire vers votre application après l’authentification. Sans URL correspondante, le processus de connexion échouera et les utilisateurs verront une page d’erreur Auth0 au lieu d’accéder à votre application.

      Les **Allowed Logout URLs** sont essentielles pour offrir une expérience utilisateur fluide lors de la déconnexion. Sans URL correspondante, les utilisateurs ne seront pas redirigés vers votre application après la déconnexion et se retrouveront plutôt sur une page Auth0 générique.

      Le format de l’URL de rappel est le suivant : `{customScheme}://{yourDomain}/{platform}/{bundleIdentifier or packageName}/callback`. Le schéma d’URL utilise le `customScheme` de votre `app.json`, mais le chemin contient toujours le `bundleIdentifier` (iOS) ou le `package` (Android) — et non le schéma personnalisé. Si vous ne précisez pas de `customScheme`, le SDK utilise par défaut `{bundleIdentifier}.auth0` / `{packageName}.auth0` comme schéma d’URL.
    </Info>

    <Warning>
      **Important** : Assurez-vous que le `customScheme` de vos URL de rappel correspond exactement à la valeur indiquée dans la configuration du plugin de votre `app.json` et que le chemin contient bien votre véritable `bundleIdentifier` (iOS) ou `package` (Android). Des valeurs qui ne correspondent pas entraîneront un échec de l’authentification.
    </Warning>
  </Step>

  <Step title="Configurer le composant d’application" stepNumber={5}>
    Configurez votre composant d'application principal selon l'approche de mise en œuvre choisie.

    <Tabs>
      <Tab title="Basé sur les Hooks (avec Provider)">
        Remplacez le contenu de `App.js` et entourez votre application du composant `Auth0Provider` :

        ```jsx App.js lines theme={null}
        import React from 'react';
        import {Auth0Provider, useAuth0} from 'react-native-auth0';
        import {
          StyleSheet,
          Text,
          View,
          Button,
          Image,
          ActivityIndicator,
        } from 'react-native';

        function HomeScreen() {
          const {authorize, clearSession, user, isLoading} = useAuth0();

          const handleLogin = async () => {
            try {
              await authorize({customScheme: 'auth0sample', scope: 'openid profile email'});
            } catch (e) {
              console.error('Login error:', e);
            }
          };

          const handleLogout = async () => {
            try {
              await clearSession({customScheme: 'auth0sample'});
            } catch (e) {
              console.error('Logout error:', e);
            }
          };

          if (isLoading) {
            return (
              <View style={styles.container}>
                <ActivityIndicator size="large" color="#0066cc" />
                <Text style={styles.loadingText}>Loading...</Text>
              </View>
            );
          }

          return (
            <View style={styles.container}>
              <Text style={styles.title}>Auth0 Expo Sample</Text>

              {user ? (
                <View style={styles.profileContainer}>
                  {user.picture && (
                    <Image source={{uri: user.picture}} style={styles.avatar} />
                  )}
                  <Text style={styles.welcomeText}>Welcome, {user.name}!</Text>
                  <Text style={styles.emailText}>{user.email}</Text>
                  <View style={styles.buttonContainer}>
                    <Button title="Log Out" onPress={handleLogout} color="#dc3545" />
                  </View>
                </View>
              ) : (
                <View style={styles.loginContainer}>
                  <Text style={styles.subtitle}>
                    Tap the button below to log in
                  </Text>
                  <View style={styles.buttonContainer}>
                    <Button title="Log In" onPress={handleLogin} color="#0066cc" />
                  </View>
                </View>
              )}
            </View>
          );
        }

        export default function App() {
          return (
            <Auth0Provider domain="{yourDomain}" clientId="{yourClientId}">
              <HomeScreen />
            </Auth0Provider>
          );
        }

        const styles = StyleSheet.create({
          container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            padding: 20,
            backgroundColor: '#fff',
          },
          title: {
            fontSize: 28,
            fontWeight: 'bold',
            marginBottom: 20,
            color: '#333',
          },
          subtitle: {
            fontSize: 16,
            color: '#666',
            marginBottom: 30,
            textAlign: 'center',
          },
          loadingText: {
            marginTop: 10,
            fontSize: 16,
            color: '#666',
          },
          profileContainer: {
            alignItems: 'center',
          },
          avatar: {
            width: 100,
            height: 100,
            borderRadius: 50,
            marginBottom: 20,
          },
          welcomeText: {
            fontSize: 22,
            fontWeight: '600',
            marginBottom: 8,
            color: '#333',
          },
          emailText: {
            fontSize: 16,
            color: '#666',
            marginBottom: 30,
          },
          loginContainer: {
            alignItems: 'center',
          },
          buttonContainer: {
            width: 200,
            marginTop: 10,
          },
        });
        ```

        Remplacez `{yourDomain}` par votre domaine Auth0 et `{yourClientId}` par votre Client ID dans l’Auth0 Dashboard.

        <Tip>
          `Auth0Provider` initialise le SDK et fournit le contexte d’authentification à tous les composants enfants via le hook `useAuth0`. Le paramètre `customScheme` doit correspondre à la valeur indiquée dans la configuration du plugin `app.json`.
        </Tip>
      </Tab>

      <Tab title="Basé sur des classes (sans Provider)">
        Remplacez le contenu de `App.js` par un composant à base de classe :

        ```jsx App.js lines theme={null}
        import React, {Component} from 'react';
        import {
          View,
          Text,
          Button,
          StyleSheet,
          ActivityIndicator,
          Image,
        } from 'react-native';
        import Auth0, {Credentials} from 'react-native-auth0';

        const auth0 = new Auth0({
          domain: '{yourDomain}',
          clientId: '{yourClientId}',
        });

        interface User {
          name?: string;
          email?: string;
          picture?: string;
        }

        interface AppState {
          user: User | null;
          isLoading: boolean;
        }

        class App extends Component<{}, AppState> {
          constructor(props: {}) {
            super(props);
            this.state = {
              user: null,
              isLoading: true,
            };
          }

          async componentDidMount() {
            await this.checkAuthStatus();
          }

          checkAuthStatus = async () => {
            try {
              const hasValidCredentials = await auth0.credentialsManager.hasValidCredentials();
              if (hasValidCredentials) {
                const credentials = await auth0.credentialsManager.getCredentials();
                const userInfo = await auth0.auth.userInfo({token: credentials.accessToken});
                this.setState({user: userInfo, isLoading: false});
              } else {
                this.setState({isLoading: false});
              }
            } catch (e) {
              console.error(e);
              this.setState({isLoading: false});
            }
          };

          login = async () => {
            try {
              const credentials: Credentials = await auth0.webAuth.authorize({
                scope: 'openid profile email',
              }, {customScheme: 'auth0sample'});
              
              await auth0.credentialsManager.saveCredentials(credentials);
              const userInfo = await auth0.auth.userInfo({token: credentials.accessToken});
              this.setState({user: userInfo});
            } catch (e) {
              console.error(e);
            }
          };

          logout = async () => {
            try {
              await auth0.webAuth.clearSession({}, {customScheme: 'auth0sample'});
              await auth0.credentialsManager.clearCredentials();
              this.setState({user: null});
            } catch (e) {
              console.error(e);
            }
          };

          render() {
            const {user, isLoading} = this.state;

            if (isLoading) {
              return (
                <View style={styles.container}>
                  <ActivityIndicator size="large" color="#0066cc" />
                  <Text style={styles.loadingText}>Loading...</Text>
                </View>
              );
            }

            return (
              <View style={styles.container}>
                <Text style={styles.title}>Auth0 Expo Sample</Text>

                {user ? (
                  <View style={styles.profileContainer}>
                    {user.picture && (
                      <Image source={{uri: user.picture}} style={styles.avatar} />
                    )}
                    <Text style={styles.welcomeText}>Welcome, {user.name}!</Text>
                    <Text style={styles.emailText}>{user.email}</Text>
                    <View style={styles.buttonContainer}>
                      <Button title="Log Out" onPress={this.logout} color="#dc3545" />
                    </View>
                  </View>
                ) : (
                  <View style={styles.loginContainer}>
                    <Text style={styles.subtitle}>
                      Tap the button below to log in
                    </Text>
                    <View style={styles.buttonContainer}>
                      <Button title="Log In" onPress={this.login} color="#0066cc" />
                    </View>
                  </View>
                )}
              </View>
            );
          }
        }

        const styles = StyleSheet.create({
          container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
            padding: 20,
            backgroundColor: '#fff',
          },
          title: {
            fontSize: 28,
            fontWeight: 'bold',
            marginBottom: 20,
            color: '#333',
          },
          subtitle: {
            fontSize: 16,
            color: '#666',
            marginBottom: 30,
            textAlign: 'center',
          },
          loadingText: {
            marginTop: 10,
            fontSize: 16,
            color: '#666',
          },
          profileContainer: {
            alignItems: 'center',
          },
          avatar: {
            width: 100,
            height: 100,
            borderRadius: 50,
            marginBottom: 20,
          },
          welcomeText: {
            fontSize: 22,
            fontWeight: '600',
            marginBottom: 8,
            color: '#333',
          },
          emailText: {
            fontSize: 16,
            color: '#666',
            marginBottom: 30,
          },
          loginContainer: {
            alignItems: 'center',
          },
          buttonContainer: {
            width: 200,
            marginTop: 10,
          },
        });

        export default App;
        ```

        Remplacez `{yourDomain}` par votre domaine Auth0 et `{yourClientId}` par votre Client ID provenant du Auth0 Dashboard.

        <Tip>
          L’approche basée sur les classes ne nécessite pas `Auth0Provider`, puisqu’elle utilise directement l’instance de la classe `Auth0`. L’option `customScheme` doit être passée comme deuxième paramètre à `authorize()` et `clearSession()`.
        </Tip>
      </Tab>
    </Tabs>

    <Info>
      La méthode `authorize()` ouvre Universal Login d’Auth0 dans un navigateur sécurisé (ASWebAuthenticationSession sur iOS, Chrome Custom Tabs sur Android). La méthode `clearSession()` déconnecte l’utilisateur et efface à la fois la session du navigateur et les informations d’authentification stockées. Le paramètre `customScheme` doit correspondre à la valeur indiquée dans la configuration du plugin de votre `app.json`.
    </Info>
  </Step>

  <Step title="Lancez votre application" stepNumber={6}>
    Compilez et lancez votre application Expo sur un appareil ou un émulateur.

    **D’abord, générez les projets natifs iOS et Android :**

    ```bash theme={null}
    npx expo prebuild
    ```

    **Ensuite, sur votre plateforme cible, exécutez :**

    **Pour iOS :**

    ```bash theme={null}
    npx expo run:ios
    ```

    **Pour Android :**

    ```bash theme={null}
    npx expo run:android
    ```

    **Déroulement attendu :**

    1. L’application se lance et affiche le bouton "Se connecter"
    2. Touchez **Se connecter** → Le navigateur s’ouvre avec Auth0 Universal Login
    3. Terminez la connexion (créez un compte ou connectez-vous)
    4. Le navigateur se ferme → Retour automatique à l’application
    5. Le profil utilisateur s’affiche avec le nom, l’adresse courriel et l’avatar

    <Tip>
      Si vous modifiez la configuration du plugin dans `app.json`, exécutez `npx expo prebuild --clean` pour régénérer les projets natifs avec la configuration mise à jour.
    </Tip>

    <Warning>
      Le simulateur iOS nécessite un compte Apple Developer valide pour ASWebAuthenticationSession. Pour tester dans le simulateur sans compte, utilisez plutôt un appareil physique ou un émulateur Android.
    </Warning>
  </Step>
</Steps>

<Check>
  **Vérification**

  Vous devriez maintenant disposer d’une expérience de connexion Auth0 entièrement fonctionnelle sur votre appareil ou votre émulateur. L’application utilise l’authentification sécurisée dans le navigateur et gère automatiquement les identifiants dans le stockage sécurisé de l’appareil.
</Check>

***

<div id="troubleshooting-advanced">
  ## Dépannage et options avancées
</div>

<Accordion title="Problèmes courants et solutions">
  ### "Invariant Violation: Native module cannot be null"

  Cette erreur se produit lorsque vous tentez d’utiliser le SDK avec Expo Go.

  **Solution :**

  Le SDK Auth0 nécessite du code natif personnalisé qui n’est pas disponible dans Expo Go. Utilisez plutôt une version de développement :

  ```bash theme={null}
  npx expo run:ios
  # ou
  npx expo run:android
  ```

  ### Erreur de non-correspondance de l’URL de rappel

  **Solution :**

  Vérifiez que ces trois éléments correspondent exactement :

  1. `customScheme` dans la configuration du plugin de `app.json`
  2. le paramètre `customScheme` transmis à `authorize()` et `clearSession()`
  3. les URL de rappel dans Auth0 Dashboard (Applications → Your App → Settings → Application URIs)

  ### Erreur "PKCE not allowed"

  **Correctif :**

  1. Allez dans Auth0 Dashboard → Applications → Your Application
  2. Remplacez le type d’application par **Native**
  3. Enregistrez les modifications et réessayez

  ### Le prebuild échoue ou le plugin n’est pas appliqué

  **Correctif :**

  ```bash theme={null}
  # Nettoyer et régénérer les projets natifs
  npx expo prebuild --clean
  ```

  ### La build iOS échoue avec des erreurs Pod

  **Correctif :**

  ```bash theme={null}
  cd ios
  pod install --repo-update
  cd ..
  npx expo run:ios
  ```

  ### Erreur d’annulation par l’utilisateur

  Gérez-la correctement dans votre fonction de connexion :

  ```jsx expandable theme={null}
  const handleLogin = async () => {
    try {
      await authorize({customScheme: 'auth0sample', scope: 'openid profile email'});
    } catch (e) {
      if (e.message === 'a0.session.user_cancelled') {
        // L’utilisateur a fermé l’écran de connexion - gérez cela correctement
        console.log('Login cancelled by user');
      } else {
        console.error('Login failed:', e);
      }
    }
  };
  ```

  ### Boîte de dialogue d’alerte iOS

  Sur iOS, les utilisateurs voient une boîte de dialogue d’autorisation : *"App Name" Wants to Use "auth0.com" to Sign In*. Il s’agit du comportement attendu de `ASWebAuthenticationSession`. Les utilisateurs doivent appuyer sur **Continue** pour continuer.

  Pour personnaliser ce comportement, vous pouvez utiliser des sessions éphémères (ce qui désactive le SSO) :

  ```jsx theme={null}
  await authorize({customScheme: 'auth0sample', scope: 'openid profile email'}, {ephemeralSession: true});
  ```
</Accordion>

<Accordion title="Récupération des jetons d’accès">
  Utilisez la méthode `getCredentials()` pour récupérer des jetons pour les appels d’API :

  ```jsx expandable lines theme={null}
  import {useAuth0} from 'react-native-auth0';

  const MyComponent = () => {
    const {getCredentials} = useAuth0();

    const callApi = async () => {
      try {
        const credentials = await getCredentials();
        const response = await fetch('https://your-api.com/endpoint', {
          headers: {
            Authorization: `Bearer ${credentials.accessToken}`,
          },
        });
        // Handle response
      } catch (e) {
        console.error('Failed to get credentials', e);
      }
    };
  };
  ```

  <Tip>
    Incluez la portée `offline_access` pendant la connexion pour recevoir un jeton d’actualisation : `authorize({customScheme: 'auth0sample', scope: 'openid profile email offline_access'})`. Cela permet le renouvellement automatique du jeton.
  </Tip>
</Accordion>

<Accordion title="Vérifier le statut d’authentification au lancement de l’application">
  Utilisez `hasValidCredentials()` pour vérifier si l’utilisateur est déjà connecté :

  ```jsx expandable lines theme={null}
  import {useAuth0} from 'react-native-auth0';
  import {useEffect} from 'react';

  const App = () => {
    const {hasValidCredentials, getCredentials} = useAuth0();

    useEffect(() => {
      const checkAuth = async () => {
        const isLoggedIn = await hasValidCredentials();
        if (isLoggedIn) {
          const credentials = await getCredentials();
          // User is authenticated, load their data
        }
      };
      checkAuth();
    }, []);
  };
  ```
</Accordion>

<Accordion title="Déploiement en production avec EAS Build">
  Pour les builds de production, utilisez EAS Build plutôt que des builds de développement local.

  **Installez EAS CLI :**

  ```bash theme={null}
  npm install -g eas-cli
  ```

  **Créez `eas.json` à la racine de votre projet :**

  ```json eas.json lines theme={null}
  {
    "cli": {
      "version": ">= 3.0.0"
    },
    "build": {
      "development": {
        "developmentClient": true,
        "distribution": "internal"
      },
      "preview": {
        "distribution": "internal"
      },
      "production": {}
    }
  }
  ```

  **Générez une build de production :**

  ```bash theme={null}
  # Générer une build pour les deux plateformes
  eas build --platform all

  # Ou générer une build pour une plateforme précise
  eas build --platform ios
  eas build --platform android
  ```

  ### Avant de déployer en production

  **Utilisez des URL de rappel HTTPS** pour une sécurité renforcée :

  ```text theme={null}
  https://{yourDomain}/ios/{bundleId}/callback
  https://{yourDomain}/android/{packageName}/callback
  ```

  **Configurez Android App Links** dans le Auth0 Dashboard :

  * Settings → Advanced Settings → Device Settings
  * Ajoutez l’empreinte SHA-256 de votre app

  **Configurez les Universal Links sur iOS :**

  * Ajoutez la capacité Associated Domains dans Xcode
  * Ajoutez `webcredentials:{yourDomain}` à Associated Domains

  **Vérifiez les paramètres de sécurité** dans le Auth0 Dashboard :

  * Activez **OIDC Conformant** dans Advanced Settings
  * Configurez correctement **l’expiration du jeton**
  * Configurez **Brute Force Protection**
  * Faites des tests sur plusieurs appareils et versions du système d’exploitation
  * Prévoyez une gestion adéquate des erreurs en cas de problèmes réseau

  <Tip>
    Pour les apps de production, envisagez d’utiliser des URL de rappel HTTPS avec des Universal Links (iOS) et des App Links (Android) plutôt que des schémas personnalisés pour une sécurité renforcée.
  </Tip>
</Accordion>

* [Application d’exemple](https://github.com/auth0-samples/auth0-react-native-sample/tree/master/00-Login-Expo)
* [Guide de migration (v4 vers v5)](https://github.com/auth0/react-native-auth0/blob/master/MIGRATION_GUIDE.md)
