Configurer la connexion Google avec Clerk sur Expo React Native

Par coderoe · 5 min de lecture

React Native
Configurer la connexion Google avec Clerk sur Expo React Native

Dans ce tutoriel, nous allons configurer une authentification avec Google dans une application Expo React Native, tout en utilisant Clerk pour gérer l'authentification et les utilisateurs.

1. Créer un projet Clerk

Rends-toi sur Clerk et crée un projet.
Une fois ton projet créé, tu auras accès à ton API key et tes Publishable keys qui seront utilisées dans l’application Expo.

EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=

2. Configurer Clerk

  • Dans le Clerk Dashboard, va dans Developers → Native applications.
  • Ajouter une applications : App ID (Team ID) et Bundle ID pour IOS et Namespace, Package name et SHA-256 certificate fingerprints pour Android utiliser la commande suivante pour obtenir le Bundle ID et Package name :
npx expo prebuild
  • Puis le Allowlist for mobile SSO redirect dans votre app.json (scheme) pour la redirection :
coderoetutoclerk://(public)

3. Ajouter les dépendances nécessaires

Installe Clerk pour Expo et React Native :

npx expo install @clerk/clerk-expo expo-secure-store

4. Initialiser Clerk dans ton projet

Structure des dossiers

├── app/
│   ├── (private)      # Route connecté  
│   │   └── _layout.tsx  
│   │   └── index.tsx  
│   ├── (public)       # Route non connecté
│   │   └── _layout.tsx  
│   │   └── index.tsx  
│   └── _layout.tsx
  • Copié le code directement dans app/_layout.tsx :
import { ClerkProvider, useUser } from "@clerk/clerk-expo";
import { tokenCache } from "@clerk/clerk-expo/token-cache";
import { Stack } from "expo-router";

const RootLayout = () => {
  const { isSignedIn } = useUser();

  console.log(isSignedIn, "isSignedIn");

  if (isSignedIn === undefined) {
    return null;
  }

  return (
    <Stack>
      <Stack.Protected guard={!isSignedIn}>
        <Stack.Screen name="(public)" options={{ headerShown: false }} />
      </Stack.Protected>

      <Stack.Protected guard={isSignedIn}>
        <Stack.Screen name="(private)" options={{ headerShown: false }} />
      </Stack.Protected>
    </Stack>
  );
};

export default function Layout() {
  return (
    <ClerkProvider tokenCache={tokenCache}>
      <RootLayout />
    </ClerkProvider>
  );
}
  • Copié le code directement dans app/(public)/_layout.tsx et app/(private)/_layout.tsx :
import { Stack } from 'expo-router/stack'

export default function Layout() {
  return <Stack />
}
  • Copié le code directement dans app/(public)/index.tsx :
import * as React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { isClerkAPIResponseError, useSSO } from "@clerk/clerk-expo";
import * as AuthSession from "expo-auth-session";

export default function SignUpScreen() {
  const { startSSOFlow } = useSSO();

  const onSignInWithGoogle = async () => {
    try {
      const { createdSessionId, setActive } = await startSSOFlow({
        strategy: "oauth_google",
        redirectUrl: AuthSession.makeRedirectUri(),
      });

      if (createdSessionId) {
        setActive!({ session: createdSessionId });
      } else {
        // Error
      }
    } catch (error) {
      if (isClerkAPIResponseError(error)) {
        console.error(error.errors);
      } else {
        console.error(error);
      }
    }
  };

  return (
    <View style={styles.container}>
      <TouchableOpacity style={styles.button} onPress={onSignInWithGoogle}>
        <Text>Sign in with Google</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
    padding: 20,
  },
  button: {
    padding: 10,
    borderRadius: 10,
    alignItems: "center",
    justifyContent: "center",
    borderWidth: 1,
    borderColor: "#0000001A",
    width: "100%",
    height: 50,
  },
});
  • Copié le code directement dans app/(private)/index.tsx :
import { useUser } from '@clerk/clerk-expo'
import { StyleSheet, Text, View } from 'react-native'
import { SignOutButton } from '@/components/SignOutButton'

export default function Page() {
 const { user } = useUser()

 return (
   <View style={styles.container}>
       <Text>Hello {user?.emailAddresses[0].emailAddress}</Text>
       <Text>Tutorial by @coderoe</Text>
       <SignOutButton />
   </View>
 )
}

const styles = StyleSheet.create({
 container: {
   flex: 1,
   alignItems: 'center',
   justifyContent: 'center',
 },
});

5. Créer un composant bouton de déconnexion

Crée un fichier SignOutButton.tsx :

import { useClerk } from '@clerk/clerk-expo'
import * as Linking from 'expo-linking'
import { Text, TouchableOpacity } from 'react-native'

export const SignOutButton = () => {
  const { signOut } = useClerk()
  const handleSignOut = async () => {
    try {
      await signOut()
      Linking.openURL(Linking.createURL('/'))
    } catch (err) {
      console.error(JSON.stringify(err, null, 2))
    }
  }
  return (
    <TouchableOpacity onPress={handleSignOut}>
      <Text>Sign out</Text>
    </TouchableOpacity>
  )
}

6. Tester la connexion Google

Lance ton projet avec :

npx expo start

Puis clique sur le bouton Se connecter avec Google. Tu devrais être redirigé vers le flux OAuth Google géré par Clerk.

Vérifier dans le dashboard Clerk

Retourne dans ton Clerk Dashboard → Users et tu verras ton utilisateur ajouté automatiquement après authentification réussie.