Saltar al contenido

Configuración de Facebook Login

GitHub

En esta guía, aprenderás a configurar Facebook Login con Capgo Social Login. Necesitarás lo siguiente:

  • Una cuenta de desarrollador de Facebook
  • El package name o bundle ID de tu app
  • Acceso a una terminal para generar key hashes (Android)

Si aún no tienes una app de Facebook creada, sigue estos pasos:

  1. Crear una app de Facebook

    Sigue el tutorial para Crear una app

  2. Añadir Facebook Login a tu app

    En tu Facebook Developer Dashboard, añade el producto Facebook Login a tu app

  3. Antes de lanzar tu app al público, sigue este tutorial para publicarla

Aquí encontrarás la información clave que necesitarás para la integración:

  1. CLIENT_TOKEN:

    Dashboard de Facebook Developers para localizar el client token
  2. APP_ID:

    Dashboard de Facebook Developers para localizar el app ID
  3. APP_NAME:

    Dashboard de Facebook Developers para localizar el app name

Este plugin es compatible con Facebook Business Login para funciones y permisos empresariales. Las cuentas de empresa pueden solicitar permisos adicionales al login estándar, como la gestión de Instagram y Pages.

Los permisos de empresa compatibles incluyen:

  • instagram_basic - Acceso a Instagram Basic Display API
  • instagram_manage_insights - Acceso a Instagram Insights
  • pages_show_list - Lista de Pages gestionadas por el usuario
  • pages_read_engagement - Lectura de datos de engagement de Pages
  • pages_manage_posts - Gestión de posts en Pages
  • business_management - Gestionar activos comerciales

Consulta la Referencia de permisos de Facebook para ver la lista completa de permisos.

Requisitos de configuración:

  1. Tu app de Facebook debe estar configurada como una app de tipo Business en la Facebook Developer Console.
  2. Los permisos de Business pueden requerir Facebook App Review antes de pasar a producción.
  3. Tu app debe cumplir con las políticas de Business Use Case de 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}'],
},
});

Notas importantes:

  • Puedes probar los permisos de negocio con usuarios de prueba y apps de desarrollo antes del App Review.
  • La mayoría de los permisos de negocio requieren el App Review de Facebook antes de pasar a producción.
  • Las Business APIs tienen diferentes límites de tasa. Revisa la documentación actual de la plataforma de Facebook antes del lanzamiento.
  • Sigue la Guía de integración de Facebook Business al configurar la app.
  1. Añade el permiso de internet a tu AndroidManifest.xml

    Asegúrate de que esta línea esté presente:

    <uses-permission android:name="android.permission.INTERNET"/>
  2. Genera el hash de tu clave de Android

    Este es un paso de seguridad crucial requerido por Facebook. Abre tu terminal y ejecuta:

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

    Cuando te pida una contraseña, usa: android

  3. Añade el key hash a tu app de Facebook

    1. Ve al dashboard de tu app en Facebook Developers
    2. Navega a Settings > Basic
    3. Baja hasta la sección “Android”
    4. Haz clic en “Add Platform” si aún no has añadido Android y rellena los datos
    5. Añade el key hash que generaste
    6. Para producción, añade tanto el debug como el release key hash
  4. Actualiza tu AndroidManifest.xml para incluir:

    <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. Añade la plataforma iOS en Facebook Developer Console

    1. Ve al dashboard de tu app en Facebook Developers
    2. Navega a Settings > Basic
    3. Ve al final de la página y haz clic en “Add Platform”
    4. Selecciona iOS y completa los datos requeridos
  2. Abre tu proyecto de Xcode y ve a Info.plist

  3. Añade las siguientes entradas a tu Info.plist:

    <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. Modifica la 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)
    }
    }
    }
  1. Inicializa el login de Facebook en tu app

    import { SocialLogin } from '@capgo/capacitor-social-login';
    // Initialize during app startup
    await SocialLogin.initialize({
    facebook: {
    appId: 'APP_ID',
    clientToken: 'CLIENT_TOKEN',
    }
    })
  2. Implementa la función de 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. Obtener datos del perfil de usuario

    Tras iniciar sesión con éxito, puedes obtener información adicional del perfil:

    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);
    }
    }
    }

    Limitación del tipo de token: La getProfile llamada solo funciona si tienes un token de acceso (inicio de sesión estándar con tracking permitido). Si el usuario denegó el tracking o usas limited login (solo token JWT), esta llamada fallará. En ese caso, usa los datos de perfil de la respuesta inicial del login.

Tu backend debe gestionar dos tipos de tokens distintos porque los usuarios de iOS pueden recibir access tokens o JWT tokens según su elección en App Tracking Transparency, mientras que los usuarios de Android siempre reciben access tokens.

PlataformaConfiguración limitedLoginElección de ATT del usuarioTipo de token de resultado
iOStrueCualquieraToken JWT
iOSfalsePermite el rastreoToken de acceso
iOSfalseDeniega el rastreoToken JWT (auto-override)
AndroidCualquieraN/AAccess Token (siempre)
  1. Detectar el tipo de token y gestionarlo

    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. Ejemplo de integración con 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. Validación de JWT en el 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. Manejador genérico de tokens de backend

    // 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 estándar):

  • ✅ Android: Siempre disponible (sin restricciones de iOS)
  • ✅ iOS: Solo si el usuario permite explícitamente el tracking de la app
  • ✅ Permite acceder a Facebook Graph API
  • ✅ Tiempos de expiración más largos
  • ✅ Más datos de usuario disponibles
  • ❌ Cada vez menos común en iOS a medida que más usuarios rechazan el tracking

JWT Token (Modo Privacidad solo iOS):

  • ❌ Android: Nunca ocurre (no soportado)
  • ✅ iOS: Cuando se deniega el rastreo o limitedLogin: true
  • ✅ Respeta la privacidad del usuario en iOS
  • ❌ Solo contiene info básica del usuario
  • ❌ Tiempos de expiración más cortos
  • ❌ Sin acceso a Facebook Graph API
  • ⚠️ El escenario más común para usuarios de iOS

Comportamiento por Plataforma:

  • Apps de iOS: Debe manejar tanto access tokens como JWT tokens
  • Apps de Android: Solo es necesario manejar access tokens
  • Apps multiplataforma: Debe implementar ambos métodos de manejo de tokens

El flujo de inicio de sesión de Facebook actualizado requiere Web Crypto API para generar el nonce, que solo está disponible en contextos seguros:

// 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
// ...
}

Problema común: ionic serve con URLs HTTP se rompe la autenticación de Facebook

EntornoCrypto API disponibleFacebook Login funciona
http://localhost:3000✅ Sí✅ Sí
http://127.0.0.1:3000✅ Sí✅ Sí
http://192.168.1.100:3000❌ No❌ No
https://any-domain.com✅ Sí✅ Sí
  1. Usa localhost para pruebas web

    Ventana de terminal
    # Instead of ionic serve --host=0.0.0.0
    ionic serve --host=localhost
  2. Habilitar HTTPS en Ionic

    Ventana de terminal
    ionic serve --ssl
  3. Probar en dispositivos reales

    Ventana de terminal
    # Capacitor apps run in secure context on devices
    ionic cap run ios
    ionic cap run android
  4. Generación de nonce alternativa para desarrollo

    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));
    }
    }

Nota sobre la integración con Firebase

Sección titulada “Nota de integración con Firebase”

La documentación reciente de Firebase requiere tokens JWT con nonces para la autenticación de Facebook, independientemente de la configuración de login. Este enfoque funciona con ambos limitedLogin: true y 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
}
});

Limitación de desarrollo: Si estás usando ionic serve en una IP de red (no localhost), el login de Facebook fallará por restricciones criptográficas de API. Usa localhost o HTTPS para pruebas web.

  1. Errores de key hash en Android

    • Verifica que hayas añadido el key hash correcto al dashboard de Facebook
    • Para builds de release, asegúrate de añadir tanto el key hash de debug como el de release
    • Verifica que usas el keystore correcto al generar el hash
  2. El botón de login de Facebook no aparece

    • Verify all manifest entries are correct
    • Comprueba que tu Facebook App ID y tu Client Token sean correctos
    • Asegúrate de haber inicializado correctamente SDK
  3. Problemas comunes en iOS

    • Asegúrate de que todas las entradas de Info.plist sean correctas
    • Verifica que los URL schemes estén bien configurados
    • Comprueba que tu bundle ID coincida con el del dashboard de Facebook
  1. Antes de probar, añade usuarios de prueba en la Facebook Developer Console

    • Ve a Roles > Test Users
    • Crea un usuario de prueba
    • Usa estas credenciales para las pruebas
  2. Test both debug and release builds

    • Build de debug con el debug key hash
    • Build de release con el release key hash
    • Prueba tanto en emuladores como en dispositivos físicos

Recuerda probar todo el flujo de login, incluyendo:

  • Login exitoso
  • Cancelación del login
  • Gestión de errores
  • Funcionalidad de logout

Continúa desde la configuración de Facebook Login

Sección titulada “Continuar con la configuración de Facebook Login”

Si estás usando Configuración de Facebook Login para planificar los flujos de autenticación y de cuenta, conéctalo con Uso de @capgo/capacitor-social-login para la capacidad nativa en el uso de @capgo/capacitor-social-login, @capgo/capacitor-social-login para los detalles de implementación en @capgo/capacitor-social-login, @capgo/capacitor-passkey para el detalle de implementación en @capgo/capacitor-passkey, @capgo/capacitor-native-biometric para el detalle de implementación en @capgo/capacitor-native-biometric, y Autenticación de dos factores para el detalle de implementación en la autenticación de dos factores.