Untuk menambahkan Google Sign-In ke aplikasi Capacitor, buat Web, iOS, dan satu atau lebih Android OAuth client ID di Google Cloud, lalu install @capgo/capacitor-social-login, panggil SocialLogin.initialize({ google: { webClientId, iOSClientId } }), lalu SocialLogin.login({ provider: 'google' }). Android menggunakan Credential Manager dari Google, iOS menggunakan SDK Google Sign-In, dan web menggunakan Google Identity Services. Ketiganya mengembalikan ID token yang Anda verifikasi di server Anda.
Panduan ini membahas setiap langkah untuk Capacitor 8 pada Oktober 2026, termasuk bagian yang biasanya bermasalah: fingerprint SHA-1, kunci Play App Signing, dan skema URL iOS.
Cara kerja Google Sign-In di aplikasi Capacitor
| Platform | API native yang digunakan oleh plugin | Client ID yang diteruskan ke plugin | Pengaturan konsol lainnya |
|---|---|---|---|
| Android | Credential Manager (androidx.credentials) |
Web client ID sebagai webClientId |
Android client dengan package name dan SHA-1 |
| iOS | Google Sign-In SDK | iOS client ID sebagai iOSClientId |
Reversed client ID URL scheme di Info.plist |
| Web | Google Identity Services | Web client ID sebagai webClientId |
Asal JavaScript yang diizinkan |
Google memblokir OAuth di dalam WebView tertanam dengan disallowed_useragent error, itulah mengapa memuat halaman login Google di dalam Capacitor WebView tidak berfungsi. Plugin ini menggunakan pemilih akun native sebagai gantinya.
Langkah 1: Konfigurasi Google Cloud
Buat project dan Google Auth Platform
- Buka Google Cloud Console dan buat proyek, atau pilih yang sudah ada. Semua client ID harus berada di proyek yang sama.
- Buka Platform Autentikasi Google (layar yang sebelumnya disebut “OAuth consent screen”).
- Di bawah Branding, atur nama aplikasi yang akan dilihat pengguna, email dukungan, serta domain dan URL kebijakan privasi Anda.
- Di bawah Audiens, pilih Eksternal untuk aplikasi konsumen. Saat aplikasi dalam Pengujian, hanya akun yang tercantum di Pengguna uji yang bisa login.
- Di bawah Akses Data, biarkan scope default
openid,emaildanprofilekecuali jika butuh lebih banyak.
Anda tidak perlu publish ke production atau lolos verifikasi untuk scope dasar. Scope sensitif (Calendar, Drive, Gmail) perlu verifikasi sebelum rilis publik.
Create the client IDs
Buka Google Auth Platform > Clients (atau APIs & Services > Credentials) dan buat:
| Tipe client | Yang harus diisi | Di mana ID ditempatkan |
|---|---|---|
| Aplikasi web | Origin JavaScript yang diotorisasi untuk web build Anda (misalnya https://app.example.com, http://localhost:5173) |
webClientId |
| iOS | Bundle ID Anda, plus App Store ID dan Team ID setelah Anda memilikinya | iOSClientId |
| Android (debug) | Nama package plus SHA-1 debug | Hanya Console |
| Android (release) | Nama package plus SHA-1 upload key | Hanya Console |
| Android (Play) | Nama package plus SHA-1 Play App Signing | Hanya Console |
Dapatkan nilai 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
Untuk build Play Store, salin SHA-1 dari Play Console > Test and release > App integrity > App signing key certificate. Jika Anda perlu release keystore terlebih dahulu, yang Generator keystore Android membuatnya di browser. Panduan Google client ID kami menjelaskan lebih dalam tentang layar console.
Langkah 2: Instal plugin
bun add @capgo/capacitor-social-login
bunx cap sync
Nonaktifkan provider yang tidak Anda gunakan agar SDK-nya tidak masuk ke 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;
Jalankan bunx cap sync setelah mengganti provider.
Langkah 3: Konfigurasi iOS
Tambahkan URL scheme reversed client ID
Buka client iOS di Google Cloud dan salin Skema URL iOS, yang formatnya seperti com.googleusercontent.apps.1234567890-abcdef. Tambahkan ke ios/App/App/Info.plist sebelum penutup </dict>:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.1234567890-abcdef</string>
</array>
</dict>
</array>
Jika Anda sudah punya CFBundleURLTypes array untuk deep links, tambahkan <dict> entry baru ke dalamnya alih-alih membuat key kedua.
Biarkan Google SDK menangani callback URL
Di ios/App/App/AppDelegate.swift, import SDK dan arahkan URL ke sana sebelum 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)
}
Pertahankan ApplicationDelegateProxy panggil begitu @capacitor/app tetap menerima deep link Anda yang lain.
Langkah 4: Konfigurasi Android
Login dasar dengan scope default berfungsi tanpa perubahan native. Jika Anda meminta scope tambahan atau gunakan mode offline, plugin perlu menerima activity result, jadi MainActivity harus mengimplementasikan marker interface 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() {}
}
Tanpa itu, pemanggilan dengan scopes akan ditolak dengan “You CANNOT use scopes without modifying the main activity”.
Untuk emulator, gunakan system image dengan Google Play label dan login ke akun Google di pengaturan perangkat. Image tanpa Play services mengembalikan NoCredentialException.
Langkah 5: Konfigurasi Web
Tambahkan setiap origin tempat Anda menyajikan web build ke Web client Asal JavaScript yang diizinkan, termasuk port (http://localhost:5173). Panggil initialize awal: plugin menyuntikkan tag script Google dan login akan gagal jika dijalankan sebelum script tersebut siap.
Langkah 6: Inisialisasi dan login
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;
}
}
Respons online berisi:
| Kolom | Catatan |
|---|---|
idToken |
OpenID Connect JWT. Kirim ini ke server Anda |
accessToken |
Untuk memanggil Google APIs dari client. Bisa berupa null di Android saat hanya scope default yang diminta |
profile |
email, name, givenName, familyName, imageUrl, id |
responseType |
'online' |
Opsi tampilan khusus Android
Panduan options object menerima style: 'bottom' untuk UI bottom sheet, ditambah filterByAuthorizedAccounts dan autoSelectEnabled untuk pengguna lama. Biarkan filterByAuthorizedAccounts nonaktif jika Anda mendukung akun Family Link. forceRefreshToken: true meminta access token baru dari Android alih-alih yang di-cache.
Meminta scope tambahan
const { result } = await SocialLogin.login({
provider: 'google',
options: {
scopes: ['https://www.googleapis.com/auth/calendar.readonly'],
},
});
Remember the MainActivity perubahan di Android, dan tambahkan scope Akses Data di Google Cloud.
Mode online vs offline
| Online (default) | Offline | |
|---|---|---|
| Mengembalikan | ID token, access token, profil | serverAuthCode saja |
| Butuh backend | Hanya untuk verifikasi token | Ya, untuk menukar code |
| Google refresh token | Tetap di Google SDK di perangkat | Disimpan di server Anda |
| Gunakan saat | Anda hanya perlu tahu siapa user tersebut | Server Anda memanggil Google APIs saat user tidak aktif |
logout, isLoggedIn, refresh |
Didukung | Tidak didukung |
Mode offline di iOS memerlukan iOSServerClientId, dan di Android memerlukan MainActivity perubahan.
Logout dan pengecekan sesi
await SocialLogin.isLoggedIn({ provider: 'google' }); // { isLoggedIn: boolean }
await SocialLogin.logout({ provider: 'google' });
Di Android, logout juga membersihkan state Credential Manager, sehingga account picker muncul lagi di kesempatan berikutnya.
Langkah 7: Verifikasi ID token di server Anda
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,
};
}
Gunakan sub sebagai stable user key. Hanya link akun yang sudah ada via email jika email_verified adalah true. Menerima kedua client ID sebagai audience membuat token dari semua platform tetap valid. Lalu issue session Anda sendiri. Jika Anda menggunakan managed backend, ikuti Supabase dengan Capacitor Social Login atau panduan Google Firebase. Neon Auth menangani Google melalui redirect OAuth, yang @capgo/capacitor-neon berjalan secara native.
Pemecahan Masalah
| Error | Penyebab | Perbaikan |
|---|---|---|
[28444] Developer console is not set up correctly |
Package name, SHA-1 atau webClientId mismatch |
Gunakan Web client ID, daftarkan SHA-1 dari build yang terpasang, dan simpan semua client dalam satu proyek |
| Berfungsi di debug, gagal dari Play Store | Play menandatangani ulang aplikasi | Tambahkan Android client dengan Play App Signing SHA-1 |
[16] Account reauth failed |
Status akun di cache sudah usang, akun bukan test user, atau user menonaktifkan app | Plugin mencoba ulang sekali secara otomatis. Cek test users, External audience, dan Play signing SHA-1 |
NoCredentialException |
Tidak ada akun Google di device, atau emulator tanpa Play services | Gunakan Google Play system image dan sign in |
USER_CANCELLED langsung setelah memilih akun |
Biasanya masih mismatch SHA-1 atau client ID | Perbaiki setup console sebelum menganggapnya sebagai pembatalan asli |
| Crash iOS: “missing support for the following URL schemes” | Reversed client ID tidak ditemukan di Info.plist |
Tambahkan com.googleusercontent.apps... scheme |
| Web: “The given origin is not allowed for the given client ID” | Origin tidak ada pada klien Web | Tambahkan origin yang persis, termasuk port |
access_denied dengan “app has not completed the Google verification process” |
Akun bukan pengguna uji saat dalam mode Testing | Tambahkan di Audience > Test users |
| Layar login Google terputus di iOS | @capacitor/privacy-screen menutupi view SDK |
Panggil PrivacyScreen.disable() sebelum login |
Di Android, filter Logcat dengan GoogleProvider. Plugin mencatat nama package, SHA-1 signing, dan nilai yang disamarkan webClientId, yang bisa Anda bandingkan dengan console dalam satu menit.
Merilis dan memelihara
Perubahan di console bisa memakan waktu beberapa jam untuk menyebar, jadi jangan rotasi client ID di hari rilis. Setelah setup native ada di store build, perubahan di sisi client seperti scope, error handling, atau URL backend bisa dikirim melalui Live updates Capgo. Jika tim Anda tidak punya Mac untuk rilis iOS, Build Capgo build dan sign binary iOS di cloud.
Panduan terkait
- Cara sign in dengan Apple menggunakan Capacitor, yang akan Anda butuhkan di iOS jika Google adalah metode login utama Anda.
- Cara menambah autentikasi ke aplikasi Capacitor untuk memilih antara social login, OIDC, passkeys, dan Better Auth.
- Halaman plugin Social Login dan Dokumentasi setup Google Android.