Langsung ke konten

Setup Facebook Login

GitHub

Dalam panduan ini, Anda akan mempelajari cara setup Facebook Login dengan Capgo Social Login. Anda memerlukan hal berikut:

  • Akun Facebook Developer
  • Package name/bundle ID aplikasi Anda
  • Akses terminal untuk generate key hashes (Android)

Jika Anda belum membuat aplikasi Facebook, ikuti langkah-langkah ini:

  1. Buat Aplikasi Facebook

    Ikuti tutorial untuk Membuat Aplikasi

  2. Tambahkan Facebook Login ke aplikasi Anda

    Di Facebook Developer Dashboard Anda, tambahkan produk Facebook Login ke aplikasi Anda

  3. Sebelum merilis aplikasi Anda ke publik, ikuti langkah ini tutorial ini untuk mempublikasikannya

Berikut adalah informasi penting yang Anda butuhkan untuk integrasi:

  1. CLIENT_TOKEN:

    Dashboard developer Facebook yang menunjukkan lokasi client token
  2. APP_ID:

    Dashboard developer Facebook yang menunjukkan lokasi app ID
  3. APP_NAME:

    Dashboard developer Facebook yang menunjukkan lokasi nama app

Plugin ini mendukung Facebook Business Login untuk fitur dan izin terkait bisnis. Akun bisnis dapat meminta izin tambahan di luar login konsumen standar, termasuk manajemen Instagram dan Pages.

Izin bisnis yang didukung meliputi:

  • instagram_basic - Akses ke Instagram Basic Display API
  • instagram_manage_insights - Akses ke Instagram Insights
  • pages_show_list - Daftar Pages yang dikelola pengguna
  • pages_read_engagement - Membaca data engagement dari Pages
  • pages_manage_posts - Mengelola postingan di Pages
  • business_management - Kelola aset bisnis

Lihat Referensi Izin Facebook untuk daftar izin lengkap.

Persyaratan konfigurasi:

  1. Aplikasi Facebook Anda harus dikonfigurasi sebagai aplikasi Business di Facebook Developer Console.
  2. Izin Business mungkin memerlukan Facebook App Review sebelum digunakan di produksi.
  3. Aplikasi Anda harus mematuhi kebijakan Business Use Case dari Facebook.
await SocialLogin.initialize({
facebook: {
appId: 'your-business-app-id',
clientToken: 'your-client-token',
},
});
const res = await SocialLogin.login({
provider: 'facebook',
options: {
permissions: [
'email',
'public_profile',
'instagram_basic',
'pages_show_list',
'pages_read_engagement',
],
},
});
const profile = await SocialLogin.providerSpecificCall({
call: 'facebook#getProfile',
options: {
fields: ['id', 'name', 'email', 'instagram_business_account'],
},
});
const res = await SocialLogin.login({
provider: 'facebook',
options: {
permissions: [
'email',
'pages_show_list',
'pages_manage_posts',
'pages_read_engagement',
],
},
});
const profile = await SocialLogin.providerSpecificCall({
call: 'facebook#getProfile',
options: {
fields: ['id', 'name', 'accounts{id,name,instagram_business_account}'],
},
});

Catatan penting:

  • Anda dapat menguji izin bisnis menggunakan user uji coba dan aplikasi development sebelum App Review.
  • Sebagian besar izin bisnis memerlukan Facebook App Review sebelum digunakan di produksi.
  • Business API memiliki rate limit yang berbeda. Tinjau dokumentasi platform Facebook terbaru sebelum peluncuran.
  • Ikuti Panduan Integrasi Facebook Business saat mengonfigurasi aplikasi.
  1. Tambahkan izin internet ke AndroidManifest.xml

    Pastikan baris ini ada:

    <uses-permission android:name="android.permission.INTERNET"/>
  2. Generate Android key hash Anda

    Ini adalah langkah keamanan krusial yang diwajibkan oleh Facebook. Buka terminal Anda dan jalankan:

    Jendela terminal
    keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64 -A

    Saat diminta password, gunakan: android

  3. Tambahkan key hash ke aplikasi Facebook Anda

    1. Buka dashboard aplikasi Anda di Facebook Developers
    2. Buka Settings > Basic
    3. Scroll ke bagian “Android”
    4. Klik “Add Platform” jika Android belum ditambahkan dan isi detailnya
    5. Tambahkan key hash yang Anda generate
    6. Untuk produksi, tambahkan key hash debug dan release
  4. Perbarui file AndroidManifest.xml untuk menyertakan:

    <application>
    ...
    <activity android:name="com.facebook.FacebookActivity"
    android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
    android:label="@string/app_name" />
    <activity
    android:name="com.facebook.CustomTabActivity"
    android:exported="true">
    <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="FB[APP_ID]" />
    </intent-filter>
    </activity>
    </application>
  1. Tambahkan platform iOS di Facebook Developer Console

    1. Buka dashboard aplikasi Anda di Facebook Developers
    2. Buka Settings > Basic
    3. Scroll ke bagian paling bawah halaman dan klik “Add Platform”
    4. Pilih iOS dan isi detail yang diperlukan
  2. Buka proyek Xcode Anda dan navigasi ke Info.plist

  3. Tambahkan entri berikut ke Info.plist Anda:

    <key>FacebookAppID</key>
    <string>[APP-ID]</string>
    <key>FacebookClientToken</key>
    <string>[CLIENT-TOKEN]</string>
    <key>FacebookDisplayName</key>
    <string>[APP-NAME]</string>
    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>fbapi</string>
    <string>fb-messenger-share-api</string>
    </array>
    <key>CFBundleURLTypes</key>
    <array>
    <dict>
    <key>CFBundleURLSchemes</key>
    <array>
    <string>fb[APP-ID]</string>
    </array>
    </dict>
    </array>
  4. Ubah AppDelegate.swift

    import FBSDKCoreKit
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    // Initialize Facebook SDK
    FBSDKCoreKit.ApplicationDelegate.shared.application(
    application,
    didFinishLaunchingWithOptions: launchOptions
    )
    return true
    }
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    // Called when the app was launched with a url. Feel free to add additional processing here,
    // but if you want the App API to support tracking app url opens, make sure to keep this call
    if (FBSDKCoreKit.ApplicationDelegate.shared.application(
    app,
    open: url,
    sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
    annotation: options[UIApplication.OpenURLOptionsKey.annotation]
    )) {
    return true;
    } else {
    return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
    }
    }
    }

Menggunakan Facebook Login di Aplikasi Anda

Bagian berjudul “Using Facebook Login in Your App”
  1. Inisialisasi login Facebook di aplikasi Anda

    import { SocialLogin } from '@capgo/capacitor-social-login';
    // Initialize during app startup
    await SocialLogin.initialize({
    facebook: {
    appId: 'APP_ID',
    clientToken: 'CLIENT_TOKEN',
    }
    })
  2. Implementasikan fungsi login

    async function loginWithFacebook() {
    try {
    const result = await SocialLogin.login({
    provider: 'facebook',
    options: {
    permissions: ['email', 'public_profile'],
    limitedLogin: false // See Limited Login section below for important details
    }
    });
    console.log('Facebook login result:', result);
    // Handle successful login
    } catch (error) {
    console.error('Facebook login error:', error);
    // Handle error
    }
    }
  3. Dapatkan Data Profil Pengguna

    Setelah login berhasil, Anda dapat mengambil informasi profil tambahan:

    async function getFacebookProfile() {
    try {
    const profileResponse = await SocialLogin.providerSpecificCall({
    call: 'facebook#getProfile',
    options: {
    fields: ['id', 'name', 'email', 'first_name', 'last_name', 'picture']
    }
    });
    console.log('Facebook profile:', profileResponse.profile);
    return profileResponse.profile;
    } catch (error) {
    console.error('Failed to get Facebook profile:', error);
    return null;
    }
    }
    // Example usage after login
    async function loginAndGetProfile() {
    const loginResult = await loginWithFacebook();
    if (loginResult) {
    const profile = await getFacebookProfile();
    if (profile) {
    console.log('User ID:', profile.id);
    console.log('Name:', profile.name);
    console.log('Email:', profile.email);
    console.log('Profile Picture:', profile.picture?.data?.url);
    }
    }
    }

    Batasan Tipe Token: getProfile hanya berfungsi jika Anda memiliki access token (login standar dengan pelacakan diizinkan). Jika pengguna menolak pelacakan atau Anda menggunakan limited login (hanya token JWT), pemanggilan ini akan gagal. Jika demikian, gunakan data profil yang disediakan dalam respons login awal.

Backend Anda harus menangani dua tipe token berbeda karena pengguna iOS bisa menerima access token atau JWT token tergantung pilihan App Tracking Transparency mereka, sedangkan pengguna Android selalu menerima access token.

PlatformPengaturan limitedLoginPilihan ATT UserTipe Token Hasil
iOStrueSemuaToken JWT
iOSfalseIzinkan trackingAccess Token
iOSfalseTolak trackingToken JWT (auto-override)
AndroidSemuaN/AAccess Token (selalu)
  1. Deteksi Tipe Token dan Tangani Sesuai

    async function loginWithFacebook() {
    try {
    const loginResult = await SocialLogin.login({
    provider: 'facebook',
    options: {
    permissions: ['email', 'public_profile'],
    limitedLogin: false // iOS: depends on ATT, Android: ignored
    }
    });
    if (loginResult.accessToken) {
    // Access token (Android always, iOS when tracking allowed)
    return handleAccessToken(loginResult.accessToken.token);
    } else if (loginResult.idToken) {
    // JWT token (iOS only when tracking denied or limitedLogin: true)
    return handleJWTToken(loginResult.idToken);
    }
    } catch (error) {
    console.error('Facebook login error:', error);
    }
    }
  2. Contoh Integrasi Firebase

    import { OAuthProvider, FacebookAuthProvider, signInWithCredential } from 'firebase/auth';
    async function handleAccessToken(accessToken: string, nonce: string) {
    // For access tokens, use OAuthProvider (new method)
    const fbOAuth = new OAuthProvider("facebook.com");
    const credential = fbOAuth.credential({
    idToken: accessToken,
    rawNonce: nonce
    });
    try {
    const userResponse = await signInWithCredential(auth, credential);
    return userResponse;
    } catch (error) {
    console.error('Firebase OAuth error:', error);
    return false;
    }
    }
    async function handleJWTToken(jwtToken: string) {
    // For JWT tokens, send to your backend for validation
    try {
    const response = await fetch('/api/auth/facebook-jwt', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    },
    body: JSON.stringify({ jwtToken })
    });
    const result = await response.json();
    return result;
    } catch (error) {
    console.error('JWT validation error:', error);
    return false;
    }
    }
  3. Validasi JWT Backend

    // Backend: Validate JWT token from Facebook
    import jwt from 'jsonwebtoken';
    import { Request, Response } from 'express';
    app.post('/api/auth/facebook-jwt', async (req: Request, res: Response) => {
    const { jwtToken } = req.body;
    try {
    // Verify JWT token with Facebook's public key
    // See: https://developers.facebook.com/docs/facebook-login/limited-login/token/validating/#standard-claims
    const decoded = jwt.verify(jwtToken, getFacebookPublicKey(), {
    algorithms: ['RS256'],
    audience: process.env.FACEBOOK_APP_ID,
    issuer: 'https://www.facebook.com' // From: https://www.facebook.com/.well-known/openid-configuration/?_rdr
    });
    // Extract user info from JWT
    const userInfo = {
    id: decoded.sub,
    email: decoded.email,
    name: decoded.name,
    isJWTAuth: true
    };
    // Create your app's session/token
    const sessionToken = createUserSession(userInfo);
    res.json({
    success: true,
    token: sessionToken,
    user: userInfo
    });
    } catch (error) {
    console.error('JWT validation failed:', error);
    res.status(401).json({ success: false, error: 'Invalid token' });
    }
    });
  4. Penanganan Token Backend Umum

    // Handle both token types in your backend
    async function authenticateFacebookUser(tokenData: any) {
    if (tokenData.accessToken) {
    // Handle access token - validate with Facebook Graph API
    const response = await fetch(`https://graph.facebook.com/me?access_token=${tokenData.accessToken}&fields=id,name,email`);
    const userInfo = await response.json();
    return {
    user: userInfo,
    tokenType: 'access_token',
    expiresIn: tokenData.expiresIn || 3600
    };
    } else if (tokenData.jwtToken) {
    // Handle JWT token - decode and validate
    // See: https://developers.facebook.com/docs/facebook-login/limited-login/token/validating/#standard-claims
    const decoded = jwt.verify(tokenData.jwtToken, getFacebookPublicKey());
    return {
    user: {
    id: decoded.sub,
    name: decoded.name,
    email: decoded.email
    },
    tokenType: 'jwt',
    expiresIn: decoded.exp - Math.floor(Date.now() / 1000)
    };
    } else {
    throw new Error('No valid token provided');
    }
    }

Access Token (Login Standar):

  • ✅ Android: Selalu tersedia (batasan iOS tidak berlaku)
  • ✅ iOS: Hanya jika user mengizinkan app tracking
  • ✅ Bisa digunakan untuk akses Facebook Graph API
  • ✅ Masa kedaluwarsa lebih lama
  • ✅ Data user lebih lengkap
  • ❌ Semakin jarang digunakan di iOS karena user semakin sering menolak tracking

JWT Token (Mode Privasi Khusus iOS):

  • ❌ Android: Tidak pernah terjadi (tidak didukung)
  • ✅ iOS: Saat pelacakan ditolak atau limitedLogin: true
  • ✅ Menghormati preferensi privasi pengguna iOS
  • ❌ Hanya berisi info dasar pengguna
  • ❌ Waktu kedaluwarsa lebih singkat
  • ❌ Tidak ada akses ke Facebook Graph API
  • ⚠️ Skenario paling umum bagi pengguna iOS saat ini

Perilaku Spesifik Platform:

  • Aplikasi iOS: Harus menangani access token DAN JWT token
  • Aplikasi Android: Hanya perlu menangani access token
  • Aplikasi Cross-platform: Harus mengimplementasikan kedua metode penanganan token

Alur login Facebook terbaru memerlukan Web Crypto API untuk pembuatan nonce, yang hanya tersedia di konteks aman:

// This requires secure context (HTTPS or localhost)
async function sha256(message: string) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer); // ❌ Fails in insecure context
// ...
}

Masalah Umum: ionic serve dengan URL HTTP merusak autentikasi Facebook

EnvironmentCrypto API TersediaFacebook Login Berjalan
http://localhost:3000✅ Ya✅ Ya
http://127.0.0.1:3000✅ Ya✅ Ya
http://192.168.1.100:3000❌ Tidak❌ Tidak
https://any-domain.com✅ Ya✅ Ya
  1. Gunakan localhost untuk testing web

    Jendela terminal
    # Instead of ionic serve --host=0.0.0.0
    ionic serve --host=localhost
  2. Aktifkan HTTPS di Ionic

    Jendela terminal
    ionic serve --ssl
  3. Tes di perangkat asli

    Jendela terminal
    # Capacitor apps run in secure context on devices
    ionic cap run ios
    ionic cap run android
  4. Alternatif pembuatan nonce untuk development

    async function generateNonce() {
    if (typeof crypto !== 'undefined' && crypto.subtle) {
    // Secure context - use crypto.subtle
    return await sha256(Math.random().toString(36).substring(2, 10));
    } else {
    // Fallback for development (not secure for production)
    console.warn('Using fallback nonce - not secure for production');
    return btoa(Math.random().toString(36).substring(2, 10));
    }
    }

Dokumentasi Firebase terbaru mewajibkan JWT token dengan nonce untuk autentikasi Facebook, apa pun pengaturan loginnya. Pendekatan ini bekerja dengan limitedLogin: true dan limitedLogin: false:

// Both modes can return JWT tokens depending on user choice
const loginResult = await SocialLogin.login({
provider: 'facebook',
options: {
permissions: ['email', 'public_profile'],
limitedLogin: false, // true = always JWT, false = depends on user tracking choice
nonce: nonce
}
});

Batasan Pengembangan: Jika Anda menggunakan ionic serve pada IP jaringan (bukan localhost), login Facebook akan gagal karena batasan kripto API. Gunakan localhost atau HTTPS untuk testing web.

  1. Error key hash pada Android

    • Pastikan Anda sudah menambahkan key hash yang benar ke dashboard Facebook
    • Untuk release build, pastikan Anda sudah menambahkan key hash debug dan release
    • Verifikasi bahwa Anda menggunakan keystore yang benar saat generate hash
  2. Tombol login Facebook tidak muncul

    • Verifikasi semua entri manifest sudah benar
    • Pastikan Facebook App ID dan Client Token Anda sudah benar
    • Pastikan Anda sudah menginisialisasi SDK dengan benar
  3. Masalah umum pada iOS

    • Pastikan semua entri Info.plist sudah benar
    • Pastikan URL scheme sudah dikonfigurasi dengan benar
    • Pastikan bundle ID sesuai dengan yang terdaftar di dashboard Facebook
  1. Sebelum testing, tambahkan test user di Facebook Developer Console

    • Buka menu Roles > Test Users
    • Buat test user baru
    • Gunakan kredensial ini untuk testing
  2. Test pada build debug maupun release

    • Build debug dengan debug key hash
    • Build release dengan release key hash
    • Test di emulator maupun perangkat fisik

Jangan lupa tes seluruh alur login, termasuk:

  • Login berhasil
  • Pembatalan login
  • Penanganan error
  • Logout functionality

Jika Anda menggunakan Setup Facebook Login untuk merencanakan alur autentikasi dan akun, hubungkan dengan Menggunakan @capgo/capacitor-social-login untuk kapabilitas native di Menggunakan @capgo/capacitor-social-login, @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, dan Autentikasi dua faktor untuk detail implementasi di autentikasi dua faktor.