Pour ajouter Google Sign-In à une application Capacitor, créez un client OAuth Web, un client iOS et un ou plusieurs clients Android dans Google Cloud, puis installez @capgo/capacitor-social-login, appelez SocialLogin.initialize({ google: { webClientId, iOSClientId } }), puis SocialLogin.login({ provider: 'google' }). Android utilise Credential Manager de Google, iOS utilise le SDK Google Sign-In SDK, et le web utilise Google Identity Services. Les trois renvoient un ID token que vous vérifiez sur votre serveur.
Ce guide détaille chaque étape pour Capacitor 8 en octobre 2026, y compris les points qui posent souvent problème : empreintes SHA-1, clé de signature Play App Signing et schéma d’URL iOS.
Comment fonctionne Google Sign-In dans une application Capacitor
| Plateforme | Native API utilisé par le plugin | Client ID transmis au plugin | Autre configuration de la console |
|---|---|---|---|
| Android | Gestionnaire d’identifiants («androidx.credentials) |
Client ID Web en tant que webClientId |
Client Android avec nom de package et SHA-1 |
| iOS | Connexion Google SDK | Client ID iOS en tant que iOSClientId |
URL scheme inversée du client ID dans Info.plist |
| Le Web | Google Identity Services | ID client Web en tant que webClientId |
Origines JavaScript autorisées |
Google bloque OAuth dans les WebViews intégrées avec l’ disallowed_useragent erreur, c’est pourquoi charger la page de connexion Google dans votre WebView Capacitor ne fonctionne pas. Le plugin utilise à la place le sélecteur de comptes natif.
Étape 1 : configurer Google Cloud
Créer un projet et la Google Auth Platform
- Ouvrez Console Google Cloud et créez un projet, ou choisissez un projet existant. Tous les ID clients doivent se trouver dans le même projet.
- Ouvrez Plateforme d’authentification Google (l’écran anciennement appelé « Écran de consentement OAuth »).
- Inférieur à Image de marque, définissez le nom d’app affiché aux utilisateurs, un e-mail de support, vos domaines et l’URL de votre politique de confidentialité.
- Inférieur à Cible, choisissez Externe pour les applications grand public. Tant que l'app est en En test, seuls les comptes listés dans Test users peuvent se connecter.
- Inférieur à Accès aux données, conservez les
openid,emailetprofileles scopes, sauf si vous en avez besoin de plus.
Vous n'avez pas besoin de publier en production ni de passer la vérification pour les scopes de base. Les scopes sensibles (Calendar, Drive, Gmail) doivent être vérifiés avant toute publication publique.
Créer les identifiants de client
Accéder à Google Auth Platform > Clients (ou API et services > Identifiants) et créez :
| Type de client | Valeur à saisir | Emplacement de l’ID |
|---|---|---|
| Application web | Origines JavaScript autorisées pour votre build web (par exemple https://app.example.com, http://localhost:5173) |
webClientId |
| iOS | Votre bundle ID, ainsi que l’App Store ID et le Team ID une fois disponibles | iOSClientId |
| Android (debug) | Nom du package et SHA-1 de debug | Console uniquement |
| Android (release) | Nom du package et SHA-1 de la clé d’upload | Console uniquement |
| Android (Play) | Nom du package et SHA-1 de Play App Signing | Console uniquement |
Récupérez les valeurs SHA-1 :
# Debug key and any signing config in build.gradle
cd android && ./gradlew signingReport
# From a signed APK you actually install
keytool -printcert -jarfile android/app/build/outputs/apk/release/app-release.apk
Pour les builds Play Store, copiez le SHA-1 depuis Play Console > Test and release > App integrity > App signing key certificate. S'il vous faut d'abord un keystore de release, le générateur de keystore Android en ligne en crée un dans le navigateur. Notre guide sur l'identifiant client Google détaille les écrans de la console.
Étape 2 : Installer le plugin
bun add @capgo/capacitor-social-login
bunx cap sync
Disable providers you do not use so their SDKs stay out of the binary:
// capacitor.config.ts
import type { CapacitorConfig } from '@capacitor/cli';
const config: CapacitorConfig = {
appId: 'com.example.app',
appName: 'Example',
webDir: 'dist',
plugins: {
SocialLogin: {
providers: {
google: true,
apple: true,
facebook: false,
twitter: false,
},
},
},
};
export default config;
Exécutez bunx cap sync après avoir modifié les fournisseurs.
Étape 3 : configuration iOS
Ajouter le schéma d'URL inversé de l'ID client
Ouvrez le client iOS dans Google Cloud et copiez le schéma d'URL iOS, qui ressemble à com.googleusercontent.apps.1234567890-abcdef. Ajoutez-l’à ios/App/App/Info.plist avant la fermeture </dict>:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.1234567890-abcdef</string>
</array>
</dict>
</array>
Si vous avez déjà un CFBundleURLTypes tableau pour les deep links, ajoutez une nouvelle <dict> entrée à la place de créer une deuxième clé.
Laissez le SDK Google gérer l’URL de callback
Dans ios/App/App/AppDelegate.swift, importez le SDK et routez l’URL vers lui avant Capacitor :
import GoogleSignIn // add at the top of the file
// Replace the generated application(_:open:options:) method
func application(_ app: UIApplication, open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if GIDSignIn.sharedInstance.handle(url) {
return true
}
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
Conservez le ApplicationDelegateProxy pour que @capacitor/app continue de recevoir vos autres deep links.
Étape 4 : configuration Android
La connexion de base avec les scopes par défaut fonctionne sans modifications natives. Si vous demandez scopes supplémentaires ou utilisez le mode hors ligne, le plugin doit recevoir les résultats d’activité, donc MainActivity doit implémenter l’interface marqueur du plugin :
package com.example.app;
import android.content.Intent;
import com.getcapacitor.BridgeActivity;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginHandle;
import ee.forgr.capacitor.social.login.GoogleProvider;
import ee.forgr.capacitor.social.login.ModifiedMainActivityForSocialLoginPlugin;
import ee.forgr.capacitor.social.login.SocialLoginPlugin;
public class MainActivity extends BridgeActivity implements ModifiedMainActivityForSocialLoginPlugin {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode >= GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MIN
&& requestCode < GoogleProvider.REQUEST_AUTHORIZE_GOOGLE_MAX) {
PluginHandle handle = getBridge().getPlugin("SocialLogin");
if (handle == null) return;
Plugin plugin = handle.getInstance();
if (plugin instanceof SocialLoginPlugin) {
((SocialLoginPlugin) plugin).handleGoogleLoginIntent(requestCode, data);
}
}
}
@Override
public void IHaveModifiedTheMainActivityForTheUseWithSocialLoginPlugin() {}
}
Sans cela, les appels avec scopes sont rejetés avec « You CANNOT use scopes without modifying the main activity ».
Pour l’émulateur, utilisez une image système avec Google Play et connectez-vous à un compte Google dans les paramètres de l’appareil. Les images sans services Play renvoient NoCredentialException.
Étape 5 : configuration web
Ajoutez chaque origine depuis laquelle vous servez le build web au client Web Origines JavaScript autorisées, y compris le port (http://localhost:5173). Appeler initialize early : le plugin injecte la balise script de Google et la connexion échoue si elle s’exécute avant que le script soit prêt.
Étape 6 : Initialisation et connexion
import { SocialLogin } from '@capgo/capacitor-social-login';
const WEB_CLIENT_ID = '1234567890-web.apps.googleusercontent.com';
const IOS_CLIENT_ID = '1234567890-ios.apps.googleusercontent.com';
export async function initAuth() {
await SocialLogin.initialize({
google: {
webClientId: WEB_CLIENT_ID, // Android + web
iOSClientId: IOS_CLIENT_ID, // iOS
iOSServerClientId: WEB_CLIENT_ID, // same as webClientId, required for offline mode on iOS
mode: 'online',
},
});
}
export async function signInWithGoogle() {
try {
const { result } = await SocialLogin.login({
provider: 'google',
options: {},
});
if (result.responseType !== 'online' || !result.idToken) {
throw new Error('Expected an ID token from Google');
}
const res = await fetch('https://api.example.com/auth/google', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ idToken: result.idToken }),
});
return res.json();
} catch (error: any) {
if (error?.code === 'USER_CANCELLED') return null;
throw error;
}
}
La réponse en ligne contient :
| Champ | Notes |
|---|---|
idToken |
JWT OpenID Connect. Envoyez-l’à votre serveur |
accessToken |
Pour appeler les API Google depuis le client. Peut être null sur Android si seules les scopes par défaut sont demandées |
profile |
email, name, givenName, familyName, imageUrl, id |
responseType |
'online' |
Options d’affichage spécifiques à Android
Le options l’objet accepte style: 'bottom' pour l’interface de la bottom sheet, ainsi que filterByAuthorizedAccounts et autoSelectEnabled pour les utilisateurs existants. Laissez filterByAuthorizedAccounts désactivé si vous prenez en charge les comptes Family Link. forceRefreshToken: true demande à Android un nouveau token d’accès au lieu d’un token en cache.
Demander des scopes supplémentaires
const { result } = await SocialLogin.login({
provider: 'google',
options: {
scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
},
});
Retenez le MainActivity changement sur Android, et ajoutez le scope sous Accès aux données dans Google Cloud.
Mode en ligne vs hors ligne
| En ligne (par défaut) | Hors ligne | |
|---|---|---|
| Retourne | ID token, access token, profil | serverAuthCode uniquement |
| Backend requis | Uniquement pour vérifier le token | Oui, pour échanger le code |
| Token de rafraîchissement Google | Reste chez Google SDK sur l’appareil | Stocké sur votre serveur |
| À utiliser quand | Vous n’avez besoin que de savoir qui est l’utilisateur | Votre serveur appelle les API Google pendant que l’utilisateur est absent |
logout, isLoggedIn, refresh |
Pris en charge | Non pris en charge |
Le mode hors ligne sur iOS nécessite iOSServerClientId, et sur Android, il nécessite le MainActivity changement.
Déconnexion et vérification de session
await SocialLogin.isLoggedIn({ provider: 'google' }); // { isLoggedIn: boolean }
await SocialLogin.logout({ provider: 'google' });
Sur Android, logout efface également l'état du Credential Manager, de sorte que le sélecteur de compte réapparaît la prochaine fois.
Étape 7 : vérifier le token ID sur votre serveur
import { OAuth2Client } from 'google-auth-library';
const client = new OAuth2Client();
export async function verifyGoogleToken(idToken: string) {
const ticket = await client.verifyIdToken({
idToken,
audience: [
'1234567890-web.apps.googleusercontent.com',
'1234567890-ios.apps.googleusercontent.com',
],
});
const payload = ticket.getPayload();
if (!payload) throw new Error('Empty token payload');
return {
googleUserId: payload.sub,
email: payload.email,
emailVerified: payload.email_verified === true,
name: payload.name,
};
}
Utiliser sub comme clé utilisateur stable. N'associez un compte existant par e-mail que si email_verified est true. Accepter les deux client IDs comme audience maintient la validité des tokens de toutes les plateformes. Émettez ensuite votre propre session. Si vous utilisez un backend managé, suivez Supabase avec Capacitor Social Login ou la Guide Firebase Google. Neon Auth gère Google via une redirection OAuth, ce qui @capgo/capacitor-neon s'exécute nativement.
Troubleshooting
| Erreur | Cause | Corriger |
|---|---|---|
[28444] Developer console is not set up correctly |
Nom du package, SHA-1 ou webClientId incohérence |
Utilisez l’ID client Web, enregistrez le SHA-1 du build installé et regroupez tous les clients dans un seul projet |
| Fonctionne en debug, échoue depuis le Play Store | Play re-signe l’application | Ajoutez un client Android avec le SHA-1 de la signature Play App Signing |
[16] Account reauth failed |
État du compte en cache obsolète, compte non testeur ou application désactivée par l’utilisateur | Le plugin réessaie une fois automatiquement. Vérifiez les utilisateurs de test, l’audience externe et le SHA-1 de signature Play |
NoCredentialException |
Aucun compte Google sur l’appareil, ou émulateur sans services Play | Utilisez une image système Google Play et connectez-vous |
USER_CANCELLED juste après avoir sélectionné un compte |
Souvent encore un SHA-1 ou un client ID incompatible | Corrigez la config console avant de conclure à une vraie annulation |
| Crash iOS : « missing support for the following URL schemes » | Client ID inversé absent de Info.plist |
Ajouter le com.googleusercontent.apps... schéma |
| Web : « L'origine fournie n'est pas autorisée pour l'ID client fourni » | Origine manquante sur le client Web | Ajoutez l'origine exacte, port inclus |
access_denied avec « l'application n'a pas terminé le processus de vérification Google » |
Le compte n'est pas un utilisateur de test en mode Testing | Ajoutez-le sous Audience > Test users |
| Écran de connexion Google interrompu sur iOS | @capacitor/privacy-screen couvre la vue SDK |
Appelez PrivacyScreen.disable() avant login |
Sur Android, filtrez Logcat par GoogleProvider. Le plugin enregistre le nom du package, le SHA-1 de signature et un webClientId, que vous pourrez comparer avec la console en une minute.
Déploiement et maintenance
Les changements dans la console peuvent mettre quelques heures à se propager, ne changez donc pas vos client IDs le jour d'une release. Une fois la configuration native incluse dans un build du store, les changements côté client comme les scopes, la gestion d'erreurs ou l'URL du backend peuvent être envoyés via les live updates Capgo. Si votre équipe n'a pas de Mac pour les releases iOS, Build Capgo compile et signe le binaire iOS dans le cloud.
Guides associés
- Comment se connecter avec Apple via Capacitor, dont vous aurez besoin sur iOS si Google est votre mode de connexion principal.
- Comment ajouter l'authentification à une application Capacitor pour choisir entre social login, OIDC, passkeys et Better Auth.
- Page du plugin Social Login et le Documentation de configuration Google Android.