Langsung ke konten utama
Tutorial

Capacitor, Supabase, dan Social Auth di React

Tutorial React dan Capacitor langkah demi langkah untuk autentikasi Supabase dengan @capgo/capacitor-social-login. Native Google dan Apple sign-in, signInWithIdToken yang aman terhadap nonce, serta aplikasi Vite yang siap rilis ke mobile.

Capacitor, Supabase, dan Social Auth di React

Rilis sign-in native Google dan Apple di React aplikasi, dukung dengan Supabase Auth, dan bungkus UI yang sama di Capacitor tanpa ribet dengan redirect browser mobile. Capgo Social Login (@capgo/capacitor-social-login) menangani native provider sheets; Anda menukar provider ID token dengan sesi Supabase menggunakan signInWithIdToken.

Artikel ini memperluas panduan Supabase + Social Login kami dengan React + Vite panduan lengkap (layout proyek, provider, route, wiring Capacitor). Untuk dashboard provider dan platform keys, tetap gunakan dokumentasi integrasi Supabase dan setup umum Google + Supabase. Postingan terkait: Google sign-in dengan Capacitor, Apple sign-in dengan Capacitor, dan opsi autentikasi di Capacitor.

Table of contents

Yang akan Anda buat

  • Sebuah Vite + React + TypeScript web app dengan tombol sign-in dan debug view
  • Supabase Auth session yang dibuat dari native Google (dan opsional Apple) ID token
  • Bundle yang sama yang berjalan di Capacitor pada iOS dan Android
  • Alur Google yang aman terhadap nonce sesuai dengan aplikasi contoh plugin

Alur autentikasi keseluruhan

Dengan @capgo/capacitor-social-login, aplikasi mobile melakukan tidak mengandalkan signInWithOAuth redirect di dalam WebView. SDK native mengembalikan Token ID; Supabase memvalidasinya dan menerbitkan JWT sendiri.

Alur dari UI React melalui Capgo Social Login dan Google ke Supabase Auth

Di web, Anda tetap bisa menggunakan plugin yang sama (lihat setup web Google). Tangani semua OAuth return URL di router Anda jika nanti menambahkan fallback browser.

Aplikasi React (Vite) dasar

Buat aplikasi baru (atau gunakan codebase React yang sudah ada):

bun create vite capgo-supabase-auth --template react-ts
cd capgo-supabase-auth
bun install
bun add @supabase/supabase-js @capgo/capacitor-social-login react-router-dom @capacitor/core

Jalankan dev server:

bun run dev

Local Vite dev server setelah instal Supabase dan Social Login

Struktur folder target:

Saran struktur src untuk Supabase auth helpers dan halaman React

Tambahkan environment variables di .env.local (jangan pernah commit secrets):

VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key
VITE_GOOGLE_WEB_CLIENT_ID=your-web-client-id.apps.googleusercontent.com
VITE_GOOGLE_IOS_CLIENT_ID=your-ios-client-id.apps.googleusercontent.com
VITE_APPLE_SERVICE_ID=com.yourapp.signin
VITE_SUPABASE_APPLE_CALLBACK_URL=https://your-project-ref.supabase.co/functions/v1/apple-signin-callback

Mengapa Menggunakan Supabase dengan Social Login?

Supabase menyediakan backend-as-a-service yang tangguh dengan autentikasi bawaan, sementara @capgo/capacitor-social-login plugin menawarkan autentikasi sosial native di platform iOS, Android, dan web. Untuk integrasi Supabase yang lebih erat, @capgo/capacitor-supabase menambahkan helper auth native dan akses JWT. Keduanya menyediakan:

  • Autentikasi sosial yang seamless
  • Manajemen token yang aman
  • Kompatibilitas lintas platform
  • Integrasi database real-time
  • Manajemen user bawaan

Prerequisites

Sebelum mulai, pastikan Anda sudah memiliki:

  • Proyek Capacitor yang sudah siap
  • Akun dan proyek Supabase
  • Akun developer untuk provider sosial pilihan Anda (Google, Apple, Facebook)

Langkah 1: Instal dan konfigurasi plugin Social Login

Pertama, instal plugin Capgo Social Login:

bun add @capgo/capacitor-social-login

Jalankan bunx cap sync setelah tambahkan Capacitor dan platform native di Tambahkan Capacitor ke aplikasi React. Panduan khusus Vite di bawah ini bisa dijalankan di browser sebelum langkah tersebut.

Lihat Social Login dan Supabase halaman plugin untuk setup spesifik platform.

Langkah 2: Setup Proyek Supabase

Checklist dashboard Supabase untuk mengaktifkan sign-in Google dengan ID token

Buat dan Konfigurasikan Proyek Supabase Anda

  1. Buat proyek Supabase:

    • Buka supabase.com dan daftar/masuk
    • Klik “Proyek Baru”
    • Pilih organisasi Anda
    • Masukkan Nama Proyek (misalnya, “MyApp Auth”)
    • Atur Password Database (simpan dengan aman)
    • Pilih Region (pilih yang terdekat dengan user)
    • Klik “Buat proyek baru”
  2. Dapatkan kredensial proyek Anda:

    • Setelah dibuat, buka Pengaturan > API
    • Salin URL Proyek (misalnya, https://your-project-ref.supabase.co)
    • Salin anon publik key API
    • Simpan ini untuk digunakan nanti di aplikasi Anda

Konfigurasikan Pengaturan Autentikasi

  1. Atur pengaturan autentikasi umum:

    • Buka Autentikasi > Pengaturan
    • Di bawah Pengaturan umum:
      • Atur URL Situs ke URL aplikasi Anda (misalnya, https://yourdomain.com atau http://localhost:3000 untuk pengembangan)
      • Tambah tambahan URL Redirect jika diperlukan:
        http://localhost:3000
        https://yourdomain.com
        capacitor://localhost (for mobile apps)
  2. Konfigurasi pengaturan email (opsional tapi disarankan):

    • Di bawah Pengaturan SMTP, konfigurasikan penyedia email Anda
    • Ini mengaktifkan konfirmasi email dan reset password
    • Untuk pengembangan, Anda bisa menggunakan layanan email bawaan

Aktifkan Provider Social Authentication

  1. Buka bagian providers:
    • Buka Autentikasi > Provider di dashboard Supabase Anda
    • Anda akan melihat daftar social provider yang tersedia
    • Setiap provider memiliki Aktifkan opsi toggle dan konfigurasi

Sekarang mari kita konfigurasi setiap provider sosial secara detail:

Langkah 3: Konfigurasi Provider Sosial di Supabase

Setup Google Authentication di Supabase

Pertama, ambil kredensial Google OAuth Anda:

Ikuti panduan setup Google kami yang lengkap: Setup Google Authentication

Panduan ini mencakup:

  • Membuat Google Cloud Project
  • Setup kredensial OAuth 2.0 untuk web, iOS, dan Android
  • Konfigurasi consent screen
  • Mendapatkan Client ID dan secret yang diperlukan

Setelah selesai setup Google, konfigurasikan di Supabase:

Ikuti Panduan umum Supabase + Google untuk melihat screenshot tiap dashboard.

  1. Aktifkan provider Google di Supabase:
    • Di dashboard Supabase Anda, buka Autentikasi > Provider
    • Cari Google dan aktifkan ON
    • Tambahkan Web, iOS, dan Android client ID yang Anda buat di Google Cloud (lewati platform yang tidak Anda gunakan)
    • Klik Simpan

Penting untuk tutorial React ini: saat Anda menggunakan signInWithIdToken dengan @capgo/capacitor-social-login, Anda perlu tidak butuh OAuth client secret atau field callback URL untuk Google. Daftarkan semua client ID yang akan diterima Supabase saat validasi token dari tiap platform.

Konfigurasi Apple Authentication di Supabase

Dapatkan kredensial Apple:

Ikuti panduan setup Apple kami yang detail: Setup Apple Authentication

Panduan ini mencakup:

  • Setting up akun Apple Developer Anda
  • Membuat App IDs dan Service IDs
  • Konfigurasi capability Sign in with Apple
  • Generate private key yang dibutuhkan
  • Setup khusus platform untuk iOS, Android, dan Web

Setelah selesai setup Apple, konfigurasikan di Supabase:

  1. Aktifkan provider Apple di Supabase:
    • Buka Authentication > Providers dan aktifkan Apple ON
    • Isi konfigurasinya:
      • Client ID: iOS App ID dan Apple Service ID Anda jika merilis kedua platform, pisahkan dengan koma (contohnya com.yourapp,com.yourapp.signin). Token iOS menggunakan audience App ID; Android dan web menggunakan Service ID. Lihat Supabase Apple secara umum.
      • Untuk tutorial ini signInWithIdToken dengan @capgo/capacitor-social-login, Anda perlu tidak OAuth client secret atau Supabase OAuth callback URL pada form provider Apple.
    • Klik Simpan

Catatan: Setup autentikasi Apple adalah yang paling kompleks karena persyaratan Apple untuk Service IDs, private keys, dan redirect URL spesifik platform. Ikuti dokumentasi kami dengan teliti untuk setiap platform.

Konfigurasi Facebook Authentication di Supabase

Dapatkan kredensial Facebook:

Ikuti panduan lengkap setup Facebook kami: Setup Autentikasi Facebook

Panduan ini mencakup:

  • Membuat akun dan aplikasi Facebook Developer
  • Menambahkan produk Facebook Login
  • Konfigurasi OAuth redirect URI
  • Mendapatkan App ID, App Secret, dan Client Token
  • Konfigurasi spesifik platform untuk iOS dan Android

Setelah setup Facebook selesai, konfigurasikan di Supabase:

  1. Aktifkan provider Facebook di Supabase:
    • Buka Autentikasi > Provider dan aktifkan Facebook AKTIF
    • Isi konfigurasinya:
      • Client ID: Facebook App ID Anda
      • Client Secret: Facebook App Secret Anda
      • URL Redirect: https://your-project-ref.supabase.co/auth/v1/callback (terisi otomatis)
    • Klik “Simpan”

Penting: Pastikan untuk menambahkan Supabase callback URL (https://your-project-ref.supabase.co/auth/v1/callback) ke aplikasi Facebook Anda URI Redirect OAuth yang Valid di pengaturan Facebook Login Anda.

Catatan Penting Konfigurasi Supabase

Row Level Security (RLS):

  • Setelah setup autentikasi, aktifkan RLS pada tabel Anda
  • Buka Database > Tabel dan aktifkan Aktifkan RLS untuk setiap tabel
  • Buat policy untuk kontrol akses data berdasarkan user yang terautentikasi

Manajemen User:

  • Lihat user yang terautentikasi di Autentikasi > Pengguna
  • Pantau event autentikasi di Autentikasi > Logs
  • Atur template email di Autentikasi > Templat Email

Testing Konfigurasi:

  • Gunakan tool test autentikasi bawaan Supabase
  • Buka Authentication > Users dan klik “Undang pengguna” untuk tes alur email
  • Cek Logs bagian untuk error autentikasi

Langkah 4: Konfigurasi Plugin Social Login

Setelah Supabase dikonfigurasi, Anda perlu mengatur plugin Social Login dengan kredensial yang sesuai. Penting: Plugin membutuhkan kredensial OAuth dari provider asli (bukan dari Supabase), sementara Supabase menangani autentikasi sisi server.

Cara Kerja Alur Autentikasi

Sebelum masuk ke konfigurasi, pahami alurnya:

  1. Plugin melakukan autentikasi dengan provider sosial (Google/Apple/Facebook) secara native
  2. Plugin menerima token (access token, ID token) dari provider
  3. Aplikasi Anda mengirimkan token ini ke Supabase menggunakan signInWithIdToken()
  4. Supabase memvalidasi token dengan provider dan membuat sesi user
  5. Supabase mengembalikan token JWT sendiri untuk request terautentikasi aplikasi Anda

Konfigurasi Plugin Google

Plugin ini membutuhkan Web Client ID untuk semua platform dan opsional Client ID iOS untuk fitur khusus iOS:

import { SocialLogin } from '@capgo/capacitor-social-login';

await SocialLogin.initialize({
  google: {
    // Use the same Web Client ID you configured in Supabase
    webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
    
    // Optional: iOS Client ID for iOS-specific features
    iOSClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com',
    
    // Use online mode so the plugin returns an idToken for Supabase
    mode: 'online'
  }
});

Poin penting untuk Google:

  • Gunakan Web Client ID (bukan client ID Android/iOS) untuk webClientId field
  • Plugin ini akan berfungsi di semua platform hanya dengan Web Client ID
  • Panduan iOSClientId bersifat opsional dan hanya digunakan untuk fitur Google khusus iOS

Konfigurasi Plugin Apple

Konfigurasi Apple berbeda antara iOS dan Android:

Untuk iOS (native Apple Sign-In):

await SocialLogin.initialize({
  apple: {
    // No additional configuration needed for iOS
    // The plugin uses the native Apple Sign-In capability
  }
});

Untuk Android/Web (memerlukan Service ID). Gunakan aturan redirect yang sama dengan buildApplePluginConfig() pada panduan React:

import { Capacitor } from '@capacitor/core';

const platform = Capacitor.getPlatform();

await SocialLogin.initialize({
  apple:
    platform === 'android'
      ? {
          clientId: 'YOUR_SERVICE_ID',
          redirectUrl:
            'https://your-project-ref.supabase.co/functions/v1/apple-signin-callback',
        }
      : {
          clientId: 'YOUR_SERVICE_ID',
          redirectUrl: window.location.href,
        },
});

Poin penting untuk Apple:

  • iOS menggunakan native Sign in with Apple (tidak butuh konfigurasi tambahan)
  • Android menggunakan Service ID dan Supabase apple-signin-callback Edge Function URL Anda
  • Web menggunakan Service ID dan window.location.href, yang harus sesuai dengan Apple Return URLs

Konfigurasi Plugin Facebook

Facebook memerlukan App ID dan Client Token Anda:

await SocialLogin.initialize({
  facebook: {
    appId: 'YOUR_FACEBOOK_APP_ID',        // From Facebook Developer Dashboard
    clientToken: 'YOUR_FACEBOOK_CLIENT_TOKEN', // From Facebook Developer Dashboard
    
    // Optional: Use Facebook Limited Login (for enhanced privacy)
    limitedLogin: false // See our Facebook setup guide for important Limited Login details
  }
});

Poin penting untuk Facebook:

  • Gunakan App ID yang sama dengan di Supabase
  • Client Token ada di Basic Settings Facebook App Anda
  • limitedLogin: true mengaktifkan fitur Limited Login Facebook yang fokus pada privasi (iOS saja)
  • Penting: Lihat Panduan setup Facebook untuk informasi detail tentang Limited Login, termasuk pertimbangan ATT

Inisialisasi @capgo/capacitor-social-login satu kali saat app React boot

Selesaikan inisialisasi plugin

Begini cara inisialisasi semua provider sekaligus:

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function initializeSocialLogin() {
  await SocialLogin.initialize({
    google: {
      webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
      mode: 'online'
    },
    facebook: {
      appId: 'YOUR_FACEBOOK_APP_ID',
      clientToken: 'YOUR_FACEBOOK_CLIENT_TOKEN',
    },
    apple: {
      // Prefer buildApplePluginConfig() from the React walkthrough.
      // Android: redirectUrl = Supabase apple-signin-callback Edge Function
      // Web: redirectUrl = window.location.href
    }
  });
}

Catatan penting:

  • Panggil initialize() satu kali saat app dimulai, bukan sebelum setiap login
  • Anda hanya perlu mengonfigurasi provider yang akan dipakai
  • Kredensial di sini berasal dari provider asli, bukan dari Supabase
  • Pastikan kredensial provider sesuai dengan yang Anda konfigurasi di Supabase

Client React Supabase dan layer auth

Instal client Supabase jika Anda belum melakukannya:

bun add @supabase/supabase-js

Buat satu client untuk seluruh tree React:

// src/lib/supabaseClient.ts
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  auth: {
    autoRefreshToken: true,
    persistSession: true,
    detectSessionInUrl: false,
  },
});

Helper nonce untuk Google + Supabase

Supabase mengharapkan raw nonce di signInWithIdToken dan digest SHA-256 passed to Google. The Panduan Supabase Google mendokumentasikan alur lengkapnya. Helper minimal:

// src/auth/nonce.ts
export function getUrlSafeNonce(): string {
  const array = new Uint8Array(32);
  crypto.getRandomValues(array);
  return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');
}

export async function sha256Hex(message: string): Promise<string> {
  const data = new TextEncoder().encode(message);
  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
  return Array.from(new Uint8Array(hashBuffer), (b) => b.toString(16).padStart(2, '0')).join('');
}

export async function createGoogleNoncePair(): Promise<{ rawNonce: string; nonceDigest: string }> {
  const rawNonce = getUrlSafeNonce();
  const nonceDigest = await sha256Hex(rawNonce);
  return { rawNonce, nonceDigest };
}

Hubungkan Social Login + Supabase dalam satu modul (pola dari contoh supabaseAuthUtils.ts):

// src/auth/socialLogin.ts
import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';
import { supabase } from '../lib/supabaseClient';
import { createGoogleNoncePair } from './nonce';

export function isAppleLoginConfigured(): boolean {
  const platform = Capacitor.getPlatform();
  if (platform === 'ios') return true;
  const serviceId = import.meta.env.VITE_APPLE_SERVICE_ID;
  if (!serviceId) return false;
  if (platform === 'android') {
    return Boolean(import.meta.env.VITE_SUPABASE_APPLE_CALLBACK_URL);
  }
  if (platform === 'web') return true;
  return false;
}

function buildApplePluginConfig() {
  const platform = Capacitor.getPlatform();

  if (platform === 'ios') {
    return {};
  }

  if (platform === 'android') {
    return {
      clientId: import.meta.env.VITE_APPLE_SERVICE_ID,
      redirectUrl: import.meta.env.VITE_SUPABASE_APPLE_CALLBACK_URL,
    };
  }

  if (platform === 'web') {
    return {
      clientId: import.meta.env.VITE_APPLE_SERVICE_ID,
      redirectUrl: window.location.href,
    };
  }

  return {};
}

function isGoogleNonceMismatch(error: { message?: string }): boolean {
  return (error.message ?? '').toLowerCase().includes('nonce');
}

let initialization: Promise<void> | null = null;

export function ensureSocialLoginInitialized(): Promise<void> {
  if (!initialization) {
    const initOptions: Parameters<typeof SocialLogin.initialize>[0] = {
      google: {
        webClientId: import.meta.env.VITE_GOOGLE_WEB_CLIENT_ID,
        iOSClientId: import.meta.env.VITE_GOOGLE_IOS_CLIENT_ID,
        mode: 'online',
      },
    };

    if (isAppleLoginConfigured()) {
      initOptions.apple = buildApplePluginConfig();
    }

    initialization = SocialLogin.initialize(initOptions).catch((error) => {
      initialization = null;
      throw error;
    });
  }
  return initialization;
}

async function signInWithGoogleSupabaseOnce(allowNonceRetry: boolean) {
  await ensureSocialLoginInitialized();
  const { rawNonce, nonceDigest } = await createGoogleNoncePair();

  const result = await SocialLogin.login({
    provider: 'google',
    options: {
      scopes: ['email', 'profile'],
      nonce: nonceDigest,
    },
  });

  const googleResult = result.result;
  if (!googleResult || googleResult.responseType !== 'online' || !googleResult.idToken) {
    throw new Error('Google login did not return an ID token');
  }

  const { data, error } = await supabase.auth.signInWithIdToken({
    provider: 'google',
    token: googleResult.idToken,
    nonce: rawNonce,
  });

  if (error) {
    if (allowNonceRetry && isGoogleNonceMismatch(error)) {
      await SocialLogin.logout({ provider: 'google' });
      return signInWithGoogleSupabaseOnce(false);
    }
    throw error;
  }

  return data;
}

export async function signInWithGoogleSupabase() {
  return signInWithGoogleSupabaseOnce(true);
}

export async function signInWithAppleSupabase() {
  if (!isAppleLoginConfigured()) {
    throw new Error('Apple sign-in is not configured for this platform');
  }
  await ensureSocialLoginInitialized();
  const result = await SocialLogin.login({
    provider: 'apple',
    options: { scopes: ['email', 'name'] },
  });

  const appleIdToken = result.result?.idToken;
  if (!appleIdToken) throw new Error('Apple login did not return an idToken');

  const { data, error } = await supabase.auth.signInWithIdToken({
    provider: 'apple',
    token: appleIdToken,
  });

  if (error) throw error;
  return data;
}

export async function signOutEverywhere() {
  await supabase.auth.signOut();
  await Promise.all([
    SocialLogin.logout({ provider: 'google' }),
    SocialLogin.logout({ provider: 'apple' }),
  ]);
}

Apple initialize per platform (lihat Supabase Apple umum, Android, Web):

  • iOS: buildApplePluginConfig() mengembalikan {}. Native Sign in with Apple menggunakan bundle ID Anda. Tidak redirectUrl.
  • Android: clientId adalah Apple Service ID Anda. redirectUrl adalah Supabase Edge Function (apple-signin-callback). Deploy function tersebut, atur Apple Return URL ke endpoint itu, dan tambahkan app deep link intent filter agar flow bisa kembali ke WebView (Panduan Android Supabase Apple).
  • Web: clientId adalah Service ID Anda. redirectUrl adalah window.location.href, yang harus cocok dengan Return URL di Apple Developer Portal (Panduan Web Supabase Apple).

ensureSocialLoginInitialized() menambahkan apple provider hanya jika isAppleLoginConfigured() adalah true, jadi setup khusus Google tidak meneruskan kredensial Android atau Apple web yang kosong.

Plugin ini mengembalikan result.idToken di semua platform (AppleProviderResponse di @capgo/capacitor-social-login). Daftarkan iOS App ID dan Service ID di Supabase saat merilis untuk beberapa platform.

Ekspos state session ke komponen:

// src/auth/useAuth.tsx
import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';
import type { Session } from '@supabase/supabase-js';
import { supabase } from '../lib/supabaseClient';
import { ensureSocialLoginInitialized } from './socialLogin';

type AuthContextValue = {
  session: Session | null;
  loading: boolean;
  initError: string | null;
  clearInitError: () => void;
};

const AuthContext = createContext<AuthContextValue | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [session, setSession] = useState<Session | null>(null);
  const [loading, setLoading] = useState(true);
  const [initError, setInitError] = useState<string | null>(null);

  useEffect(() => {
    void ensureSocialLoginInitialized()
      .then(() => setInitError(null))
      .catch((error) => {
        setInitError(error instanceof Error ? error.message : 'Social login failed to initialize');
      });
    supabase.auth.getSession().then(({ data }) => {
      setSession(data.session);
      setLoading(false);
    });
    const { data: subscription } = supabase.auth.onAuthStateChange((_event, nextSession) => {
      setSession(nextSession);
    });
    return () => subscription.subscription.unsubscribe();
  }, []);

  const clearInitError = useCallback(() => setInitError(null), []);

  const value = useMemo(
    () => ({ session, loading, initError, clearInitError }),
    [session, loading, initError, clearInitError],
  );

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used inside AuthProvider');
  return ctx;
}

UI login React dan protected routes

Contoh layar login dengan tombol Google dan Apple dalam layout mobile

Panel login:

// src/components/LoginPanel.tsx
import { useState } from 'react';
import {
  isAppleLoginConfigured,
  signInWithAppleSupabase,
  signInWithGoogleSupabase,
} from '../auth/socialLogin';
import { useAuth } from '../auth/useAuth';

export function LoginPanel() {
  const { initError, clearInitError } = useAuth();
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const showApple = isAppleLoginConfigured();

  const run = async (action: () => Promise<unknown>) => {
    setBusy(true);
    setError(null);
    try {
      await action();
      clearInitError();
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Sign-in failed');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div>
      <button type="button" disabled={busy} onClick={() => run(signInWithGoogleSupabase)}>
        Continue with Google
      </button>
      {showApple ? (
        <button type="button" disabled={busy} onClick={() => run(signInWithAppleSupabase)}>
          Continue with Apple
        </button>
      ) : null}
      {initError ? <p role="alert">{initError}</p> : null}
      {error ? <p role="alert">{error}</p> : null}
    </div>
  );
}

Tampilan debug session (ganti dengan UI akun asli Anda nanti):

// src/components/SessionDebug.tsx
import { useEffect, useState } from 'react';
import type { User } from '@supabase/supabase-js';
import { supabase } from '../lib/supabaseClient';
import { signOutEverywhere } from '../auth/socialLogin';

export function SessionDebug() {
  const [user, setUser] = useState<User | null>(null);

  useEffect(() => {
    supabase.auth.getUser().then(({ data }) => setUser(data.user));
  }, []);

  return (
    <div>
      <button type="button" onClick={() => signOutEverywhere()}>Sign out</button>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </div>
  );
}

JSON session setelah login di panel debug React

Rute dengan react-router-dom:

// src/App.tsx
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import { AuthProvider, useAuth } from './auth/useAuth';
import { LoginPanel } from './components/LoginPanel';
import { SessionDebug } from './components/SessionDebug';

function HomePage() {
  const { session, loading } = useAuth();
  if (loading) return <p>Loading…</p>;
  if (session) return <Navigate to="/account" replace />;
  return <LoginPanel />;
}

function AccountPage() {
  const { session, loading } = useAuth();
  if (loading) return <p>Loading…</p>;
  if (!session) return <Navigate to="/" replace />;
  return <SessionDebug />;
}

export default function App() {
  return (
    <AuthProvider>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<HomePage />} />
          <Route path="/account" element={<AccountPage />} />
        </Routes>
      </BrowserRouter>
    </AuthProvider>
  );
}

Pasang aplikasi di main.tsx seperti biasa. Setelah login provider berhasil, onAuthStateChange update session dan React Router mengarahkan user ke /account.

Opsional: Facebook

Facebook mengikuti signInWithIdToken pola yang sama dengan access token dari plugin. Lihat setup Facebook dan blok provider di Langkah 4.

Tambahkan Capacitor ke aplikasi React

Build web bundle, lalu tambahkan proyek native:

bun run build
bun add @capacitor/core @capacitor/cli @capacitor/ios @capacitor/android
bunx cap init "Capgo Auth Demo" com.example.authdemo --web-dir dist
bunx cap add ios
bunx cap add android

Capacitor menghosting build Vite sementara SDK native menangani social login

Sync setelah setiap web build:

bun run build
bunx cap sync

Buka IDE native saat siap melakukan testing di perangkat:

bunx cap open ios
bunx cap open android

Selesaikan langkah platform Google dan Apple sebelum testing di hardware:

Tutorial yang memanggil supabase.auth.signInWithOAuth di dalam WebView sering kali butuh Universal Links atau App Links sehingga OS mengembalikan kontrol ke aplikasi setelah Google melakukan redirect. Native Google sign-in dengan Token ID menghindari loop redirect tersebut karena plugin tidak pernah membuka browser OAuth round trip. Apple di Android berbeda: tetap menggunakan redirect Edge Function dan sebuah app deep link intent filter agar WebView bisa lanjut setelah login Apple.

Anda tetap bisa mengonfigurasi deep links untuk fitur lain (email reset password, magic links, URL marketing). Tambahkan path yang sama ke Autentikasi &gt; Konfigurasi URL di Supabase dan ke apple-app-site-association / intent filters Android saat Anda menambahkan alur tersebut.

Langkah 8: Konfigurasi Spesifik Platform

Konfigurasi iOS

Untuk instruksi setup iOS yang mendalam, lihat panduan spesifik platform kami:

Ringkasan cepat - Tambahkan ke ios/App/App/Info.plist:

<!-- Google Sign-In URL scheme -->
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>YOUR_REVERSED_CLIENT_ID</string>
    </array>
  </dict>
</array>

<!-- Apple Sign-In capability -->
<key>com.apple.developer.applesignin</key>
<array>
  <string>Default</string>
</array>

Ikuti panduan terkait untuk instruksi setup iOS lengkap, termasuk konfigurasi proyek Xcode.

Konfigurasi Android

Untuk instruksi setup Android yang mendetail, lihat panduan khusus platform kami:

Setup Android esensial:

1. Dapatkan SHA-1 fingerprint Anda (wajib untuk Google):

# For debug builds (development)
cd android
./gradlew signingReport

# Look for the SHA1 fingerprint under "Variant: debug"
# Add this SHA1 to your Google Cloud Console Android OAuth client

2. Konfigurasi AndroidManifest.xml - Tambahkan ke android/app/src/main/AndroidManifest.xml:

<!-- Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- Facebook configuration -->
<meta-data 
  android:name="com.facebook.sdk.ApplicationId" 
  android:value="@string/facebook_app_id"/>
<meta-data 
  android:name="com.facebook.sdk.ClientToken" 
  android:value="@string/facebook_client_token"/>

3. Tambahkan resource Facebook ke android/app/src/main/res/values/strings.xml:

<string name="facebook_app_id">YOUR_FACEBOOK_APP_ID</string>
<string name="facebook_client_token">YOUR_FACEBOOK_CLIENT_TOKEN</string>

Ikuti panduan platform terkait untuk konfigurasi Android lengkap, termasuk setup Google Play Services dan konfigurasi package name.

Langkah 9: Menggunakan Database Supabase dengan User Terautentikasi

Setelah user terautentikasi, Anda bisa menggunakan database Supabase dengan Row Level Security (RLS):

// Example: Fetch user profile
async function getUserProfile() {
  const { data: user } = await supabase.auth.getUser();
  
  if (user) {
    const { data, error } = await supabase
      .from('profiles')
      .select('*')
      .eq('id', user.user.id)
      .single();
    
    return data;
  }
}

// Example: Update user profile
async function updateUserProfile(updates: any) {
  const { data: user } = await supabase.auth.getUser();
  
  if (user) {
    const { data, error } = await supabase
      .from('profiles')
      .update(updates)
      .eq('id', user.user.id);
    
    return data;
  }
}

Pertimbangan Keamanan Penting

  1. Jangan pernah ekspos key sensitif di code client Anda
  2. Gunakan environment variables untuk konfigurasi
  3. Aktifkan Row Level Security di Supabase
  4. Validasi token di backend jika diperlukan
  5. Tangani refresh token secara otomatis dengan Supabase

Masalah umum dan troubleshooting

Nonce mismatch pada Google (terutama iOS)

Jika Supabase mengembalikan error nonce, Google mungkin mengembalikan ID token yang tersimpan di cache. Logout dari Google melalui plugin, coba lagi sekali, dan pastikan Anda berhasil nonceDigest ke SocialLogin.login dan rawNonce ke signInWithIdToken. aplikasi contoh percobaan setelah SocialLogin.logout.

Error audience token

Daftarkan setiap Google client ID (web, iOS, Android) di provider Google Supabase. aud claim pada ID token harus cocok dengan salah satunya.

Tutorial redirect OAuth vs panduan ini

Postingan blog yang menggunakan signInWithOAuth di WebView bisa gagal di mobile saat redirect membuka Safari alih-alih aplikasi Anda. Gunakan native login + signInWithIdToken untuk Capacitor, atau ikuti setup web Social Login untuk redirect browser.

Pengecekan spesifik platform

Token tidak cocok dan error jaringan

  • Samakan kredensial provider antara Google Cloud, Supabase, dan SocialLogin.initialize
  • Tampilkan state loading dan error di React (lihat LoginPanel di atas)

Kesimpulan

Sekarang Anda punya sistem autentikasi lengkap yang menggabungkan backend Supabase yang tangguh dengan kemampuan native social login. Setup ini menyediakan:

  • Autentikasi sosial native yang aman
  • Manajemen token yang seamless
  • Integrasi database real-time
  • Kompatibilitas lintas platform

Kombinasi Supabase dan plugin Capgo Social Login menawarkan solusi autentikasi yang powerful dan scalable untuk aplikasi Capacitor Anda.

Untuk fitur yang lebih canggih seperti autentikasi multi-faktor atau custom claims, silakan cek dokumentasi Supabase dan dokumentasi plugin Social Login.

Lanjutkan dari Setup Supabase Authentication dengan Capacitor Social Login Plugin

Jika Anda menggunakan Setup Supabase Authentication dengan Capacitor Social Login Plugin untuk merencanakan alur autentikasi dan akun, hubungkan dengan @capgo/capacitor-social-login untuk detail implementasi di @capgo/capacitor-social-login, @capgo/capacitor-passkey untuk detail implementasi di @capgo/capacitor-passkey, @capgo/capacitor-native-biometric untuk detail implementasi di @capgo/capacitor-native-biometric, Autentikasi dua faktor untuk detail implementasi pada Two-factor authentication, dan SSO (Enterprise) untuk detail implementasi pada SSO (Enterprise).

Live updates untuk aplikasi Capacitor

Saat bug web-layer sudah live, kirim perbaikannya lewat Capgo alih-alih menunggu berhari-hari untuk persetujuan app store. Pengguna mendapat update di background, sementara perubahan native tetap mengikuti jalur review normal.

Terbaru dari Blog kami

Capgo memberikan insight terbaik yang Anda butuhkan untuk membuat aplikasi mobile yang benar-benar profesional.