跳过内容

Facebook登录设置

GitHub

在本指南中,您将学习如何设置 Facebook 登录与 Capgo 社交登录。您需要以下内容:

  • Facebook 开发者帐户
  • 您的应用程序的包名/捆绑 ID
  • 访问终端以生成密钥散列(Android)

基本设置

基本设置

如果您尚未创建一个Facebook应用,请遵循以下步骤:

  1. 创建Facebook应用

    遵循教程 创建应用

  2. 将Facebook登录添加到您的应用中

    在您的Facebook开发者控制台中,添加Facebook登录产品到您的应用

  3. 在发布应用之前,请遵循以下教程 发布应用 重要信息

在发布应用之前,请遵循以下教程:

重要信息

您将需要的整合关键信息的位置是这里:

  1. CLIENT_TOKEN:

    Facebook开发者控制台显示客户端令牌的位置
  2. APP_ID:

    Facebook开发者控制台显示应用ID的位置
  3. APP_NAME:

    Facebook开发者控制台显示应用名称的位置

Facebook商业登录

Facebook商业登录

本插件支持Facebook商业登录,用于商业相关功能和权限。商业账户可以请求额外的权限,包括Instagram和页面管理,超出标准消费者登录。

支持的商业权限包括:

  • instagram_basic - Instagram基本显示API的访问权限
  • instagram_manage_insights - Instagram Insights的访问权限
  • pages_show_list - 用户管理的页面列表
  • pages_read_engagement - 从 Facebook Pages 中读取参与度数据
  • pages_manage_posts - 在 Facebook Pages 中管理帖子
  • business_management - 管理商业资产

查看 Facebook 权限参考指南 以获取完整的权限列表。

配置要求:

  1. 您的 Facebook 应用程序必须在 Facebook 开发者控制台中配置为商业应用程序。
  2. 商业权限可能需要在生产环境中使用之前通过 Facebook App Review 进行审批。
  3. 您的应用程序必须符合 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}'],
},
});

重要说明:

  • 您可以使用测试用户和开发应用程序测试商业权限,
  • 在App Review之前使用商业权限。
  • 大多数商业权限在生产环境中使用之前需要Facebook App Review。
  • 商业API具有不同的速率限制。 在发布之前,请查看Facebook的当前平台文档。 配置应用程序时,请遵循

Facebook商业集成指南。

Android 设置
  1. 在您的 AndroidManifest.xml

    确保以下行存在:

    <uses-permission android:name="android.permission.INTERNET"/>
  2. 生成您的 Android 密钥哈希

    这是 Facebook 需要的关键安全步骤。打开您的终端并运行:

    终端窗口
    keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64 -A

    当被提示输入密码时,请使用: android

  3. 在 Facebook 应用中添加密钥哈希

    1. 前往 Facebook 开发者中心中的应用仪表板
    2. 导航到设置 > 基本
    3. 滚动到“Android”部分
    4. 如果 Android 没有添加,请点击“添加平台”,并填写详细信息
    5. 添加您生成的密钥哈希
    6. 在生产环境中,添加两种密钥哈希(debug 和 release)
  4. 更新您的 AndroidManifest.xml 以包含:

    <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. 在Facebook开发者控制台中添加iOS平台

    1. 前往您的应用的控制台
    2. 导航到设置>基本
    3. 滚动到页面底部并点击“添加平台”
    4. 选择iOS并填写所需详细信息
  2. 打开你的 Xcode 项目并导航到 Info.plist

  3. 在 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. 修改 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)
    }
    }
    }

在你的应用中使用 Facebook 登录

在您的应用程序中使用Facebook登录
  1. 在您的应用程序中初始化Facebook登录

    import { SocialLogin } from '@capgo/capacitor-social-login';
    // Initialize during app startup
    await SocialLogin.initialize({
    facebook: {
    appId: 'APP_ID',
    clientToken: 'CLIENT_TOKEN',
    }
    })
  2. 实现登录功能

    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. protectedTokens":["Cloudflare","Capacitor","GitHub","Capgo","code","API","SDK","CLI","npm","bun"]

    texts":["这里","获取用户资料","登录成功后,您可以获取更多的资料信息:","复制到剪贴板","提示","提示","可用资料字段",":您可以请求Facebook的图形__CAPGO_KEEP_0__中可用的任何字段,包括:","请注意,某些字段可能需要额外的权限","令牌类型限制",":仅当您有一个时该调用才有效","call"

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

    仅在您有一个时该调用才有效"类型" getProfile 限制" access token (标准登录允许跟踪). 如果用户拒绝跟踪或您正在使用有限登录(仅 JWT token),则此调用将失败。 在这种情况下,请使用初始登录响应中提供的配置文件数据。

您的后端必须处理 两个不同的令牌类型 因为 iOS 用户可以根据 App Tracking Transparency 的选择接收 access 令牌或 JWT 令牌,而 Android 用户总是接收 access 令牌。

各个平台的令牌类型

平台类型
平台受限登录设置用户ATT选择结果令牌类型
iOStrue任何JWT令牌
iOSfalse允许跟踪访问令牌
iOSfalse拒绝跟踪__CAPGO_KEEP_0__
Android任何N/A__CAPGO_KEEP_0__ (始终)

后端实现

后端实现
  1. 检测令牌类型并处理

    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. 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. 后端 JWT 验证

    // 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. 通用后端令牌处理器

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

关键考虑因素

标题:关键考虑因素

标准登录访问令牌:

  • Android: 始终可用 (iOS 限制不适用)
  • iOS: 只有当用户明确允许应用跟踪时
  • ✅ 可用于访问 Facebook Graph API
  • ✅ 更长的过期时间
  • ✅ 可获得更多用户数据
  • iOS 设备上使用率正在减少 随着用户越来越多地拒绝跟踪

JWT Token (iOS-Only Privacy Mode):

  • Android: 从未发生(不受支持)
  • iOS: 当跟踪被拒绝或 limitedLogin: true
  • ✅ 遵守 iOS 用户隐私偏好
  • ❌ 只包含基本用户信息
  • ❌ 过期时间更短
  • ❌ 无法访问 Facebook Graph API
  • ⚠️ 现在是 iOS 用户中最常见的场景

平台特定行为:

  • iOS应用: 必须处理两种类型的令牌:访问令牌和JWT令牌
  • Android应用: 只需处理访问令牌
  • 跨平台应用: 必须实现两种令牌处理方法

Secure Context Requirements (Web/Capacitor)

Section titled “Secure Context Requirements (Web/Capacitor)”

The updated Facebook login flow requires the Web Crypto API for nonce generation, which is only available in secure contexts:

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

Common Problem: ionic serve with HTTP URLs breaks Facebook authentication

环境API 加密可用Facebook 登录可用
http://localhost:3000✅ 是✅ 是
http://127.0.0.1:3000✅ 是✅ 是
http://192.168.1.100:3000❌ 否❌ 否
https://any-domain.com✅ 是✅ 是

Capacitor 开发的解决方案

解决方案Capacitor开发
  1. 使用localhost进行web测试

    终端窗口
    # Instead of ionic serve --host=0.0.0.0
    ionic serve --host=localhost
  2. 在Ionic中启用HTTPS

    终端窗口
    ionic serve --ssl
  3. 在实际设备上测试

    终端窗口
    # Capacitor apps run in secure context on devices
    ionic cap run ios
    ionic cap run android
  4. 开发环境下的替代nonce生成

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

Firebase 集成注意事项

Firebase 集成注意事项

最近的 Firebase 文档要求使用 JWT 令牌(带有非法 nonce)进行 Facebook 登录,無論登錄設定如何。这種方法适用于两种情况 limitedLogin: truelimitedLogin: 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
}
});

开发限制: 如果您在 ionic serve 上使用网络 IP(而不是 localhost),Facebook 登录将因 crypto API 限制而失败。请使用 localhost 或 HTTPS 进行 web 测试。

故障排除

故障排除

常见问题和解决方案

常见问题和解决方案
  1. Android 上的密钥哈希错误

    • 请确认您已在 Facebook 控制台中添加了正确的密钥哈希
    • 对于发布版本,请确保已添加了 debug 和 release 密钥哈希
    • 生成哈希时,请确认您正在使用正确的 keystore
  2. Facebook 登录按钮未显示

    • 请确认所有清单条目都是正确的
    • 请确认您的 Facebook App ID 和 Client Token 是正确的
    • 请确认已正确初始化 SDK
  3. 常见iOS问题

    • 确保所有Info.plist条目都是正确的
    • 验证URL方案是否正确配置
    • 检查您的包ID是否与Facebook控制台中注册的一致

测试

测试
  1. 在测试之前,在Facebook开发者控制台中添加测试用户

    • 转到角色 > 测试用户
    • 创建测试用户
    • 使用这些凭证进行测试
  2. 测试debug和release版本

    • 使用debug密钥哈希的debug版本
    • 使用发布密钥哈希发布构建
    • 在模拟器和物理设备上都进行测试

请记住测试完整的登录流程,包括:

  • 成功登录
  • 登录取消
  • 错误处理
  • 注销功能

继续从Facebook登录设置

标题:继续从Facebook登录设置

如果您正在使用 Facebook登录设置 来规划身份验证和帐户流程,连接它 使用 @capgo/capacitor-social-login 为原生能力在使用 @capgo/capacitor-social-login, @capgo/capacitor-social-login 为实现细节在 @capgo/capacitor-social-login, @capgo/capacitor-passkey 为实现细节在 @capgo/capacitor-passkey, @capgo/capacitor-native-biometric 为实现细节在 @capgo/capacitor-native-biometric, 和 双因素认证 为实现细节在双因素认证.