コンテンツへスキップ

Facebookログインの設定

このガイドでは、Capgo Social LoginでFacebookログインを設定する方法を学びます。次のものが必要です:

  • Facebook Developer Account
  • アプリのpackage name/bundle ID
  • key hashを生成するためのターミナルへのアクセス(Android)

まだFacebookアプリを作成していない場合は、次の手順に従ってください:

  1. Facebookアプリを作成する

    Create an Appのチュートリアルに従ってください

  2. アプリにFacebookログインを追加する

    Facebook Developer Dashboardで、アプリにFacebook Loginプロダクトを追加します

  3. アプリを一般公開する前に、このチュートリアルに従って公開してください

統合に必要な重要な情報の場所は次のとおりです:

  1. CLIENT_TOKEN:

    Facebook developer dashboard showing where to find the client token
  2. APP_ID:

    Facebook developer dashboard showing where to find the app ID
  3. APP_NAME:

    Facebook developer dashboard showing where to find the app name
  1. AndroidManifest.xmlにインターネット権限を追加する

    この行が存在することを確認してください:

    <uses-permission android:name="android.permission.INTERNET"/>
  2. Android key hashを生成する

    これはFacebookが要求する重要なセキュリティ手順です。ターミナルを開いて次を実行します:

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

    パスワードを求められたら、androidを使用してください

  3. key hashをFacebookアプリに追加する

    1. Facebook Developersのアプリダッシュボードにアクセスします
    2. Settings > Basicに移動します
    3. 「Android」セクションまでスクロールします
    4. Androidがまだ追加されていない場合は「Add Platform」をクリックして詳細を入力します
    5. 生成したkey hashを追加します
    6. 本番環境では、デバッグとリリースの両方のkey hashを追加します
  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 Developer ConsoleでiOSプラットフォームを追加する

    1. Facebook Developersのアプリダッシュボードにアクセスします
    2. Settings > Basicに移動します
    3. ページの一番下までスクロールして「Add Platform」をクリックします
    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ログインを使用する

Section titled “アプリでFacebookログインを使用する”
  1. アプリでFacebookログインを初期化する

    import { SocialLogin } from '@capgo/capacitor-social-login';
    // アプリ起動時に初期化
    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 // 重要な詳細については、以下のLimited Loginセクションを参照してください
    }
    });
    console.log('Facebook login result:', result);
    // ログイン成功を処理
    } catch (error) {
    console.error('Facebook login error:', error);
    // エラーを処理
    }
    }
  3. ユーザープロファイルデータを取得する

    ログインが成功した後、追加のプロファイル情報を取得できます:

    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;
    }
    }
    // ログイン後の使用例
    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(トラッキングが許可されている標準ログイン)がある場合にのみ機能します。ユーザーがトラッキングを拒否した場合、またはlimited login(JWT tokenのみ)を使用している場合、この呼び出しは失敗します。その場合は、初回ログイン応答で提供されるプロファイルデータを使用してください。

⚠️ 重要: バックエンドトークン処理

Section titled “⚠️ 重要: バックエンドトークン処理”

バックエンドは2つの異なるトークンタイプを処理する必要があります。iOSユーザーはApp Tracking Transparencyの選択に応じてaccess tokenまたはJWT tokenのいずれかを受け取る可能性があり、Androidユーザーは常にaccess tokenを受け取ります。

プラットフォーム別のトークンタイプ

Section titled “プラットフォーム別のトークンタイプ”
プラットフォームlimitedLogin設定ユーザーATT選択結果のトークンタイプ
iOStrue任意JWT Token
iOSfalseトラッキングを許可Access Token
iOSfalseトラッキングを拒否JWT Token(自動上書き)
Android任意N/AAccess Token(常に)
  1. トークンタイプを検出して適切に処理する

    async function loginWithFacebook() {
    try {
    const loginResult = await SocialLogin.login({
    provider: 'facebook',
    options: {
    permissions: ['email', 'public_profile'],
    limitedLogin: false // iOS: ATTに依存、Android: 無視される
    }
    });
    if (loginResult.accessToken) {
    // Access token(Androidは常に、iOSはトラッキングが許可されている場合)
    return handleAccessToken(loginResult.accessToken.token);
    } else if (loginResult.idToken) {
    // JWT token(iOSのみ、トラッキングが拒否された場合または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) {
    // Access tokenの場合は、OAuthProviderを使用(新しい方法)
    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) {
    // JWT tokenの場合は、バックエンドに送信して検証
    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検証

    // バックエンド: FacebookからのJWT tokenを検証
    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 {
    // Facebookの公開鍵でJWT tokenを検証
    // 参照: 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
    });
    // JWTからユーザー情報を抽出
    const userInfo = {
    id: decoded.sub,
    email: decoded.email,
    name: decoded.name,
    isJWTAuth: true
    };
    // アプリのセッション/トークンを作成
    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. 汎用バックエンドトークンハンドラ

    // バックエンドで両方のトークンタイプを処理
    async function authenticateFacebookUser(tokenData: any) {
    if (tokenData.accessToken) {
    // Access tokenを処理 - 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) {
    // JWT tokenを処理 - デコードして検証
    // 参照: 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(標準ログイン):

  • Android: 常に利用可能(iOS専用の制限は適用されません)
  • iOS: ユーザーが明示的にアプリのトラッキングを許可した場合のみ
  • ✅ Facebook Graph APIへのアクセスに使用可能
  • ✅ より長い有効期限
  • ✅ より多くのユーザーデータが利用可能
  • iOSではあまり一般的でなくなっている、ユーザーがトラッキングを拒否することが増えているため

JWT Token(iOS専用プライバシーモード):

  • Android: 発生しない(サポートされていない)
  • iOS: トラッキングが拒否された場合、またはlimitedLogin: trueの場合
  • ✅ iOSユーザーのプライバシー設定を尊重
  • ❌ 基本的なユーザー情報のみを含む
  • ❌ より短い有効期限
  • ❌ Facebook Graph APIへのアクセスなし
  • ⚠️ 現在iOSユーザーで最も一般的なシナリオ

プラットフォーム固有の動作:

  • iOSアプリ: access tokenとJWT tokenの両方を処理する必要があります
  • Androidアプリ: access tokenのみを処理する必要があります
  • クロスプラットフォームアプリ: 両方のトークン処理方法を実装する必要があります

セキュアコンテキストの要件(Web/Capacitor)

Section titled “セキュアコンテキストの要件(Web/Capacitor)”

更新されたFacebookログインフローには、nonceの生成にWeb Crypto APIが必要であり、これはセキュアコンテキストでのみ利用可能です:

// これはセキュアコンテキスト(HTTPSまたはlocalhost)が必要です
async function sha256(message: string) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer); // ❌ セキュアでないコンテキストでは失敗します
// ...
}

よくある問題: HTTP URLのionic serveがFacebook認証を壊す

環境Crypto API利用可能Facebookログイン動作
http://localhost:3000✅ はい✅ はい
http://127.0.0.1:3000✅ はい✅ はい
http://192.168.1.100:3000❌ いいえ❌ いいえ
https://any-domain.com✅ はい✅ はい
  1. Webテストにlocalhostを使用する

    Terminal window
    # ionic serve --host=0.0.0.0の代わりに
    ionic serve --host=localhost
  2. IonicでHTTPSを有効にする

    Terminal window
    ionic serve --ssl
  3. 実機でテストする

    Terminal window
    # Capacitorアプリは実機上でセキュアコンテキストで実行されます
    ionic cap run ios
    ionic cap run android
  4. 開発用の代替nonce生成

    async function generateNonce() {
    if (typeof crypto !== 'undefined' && crypto.subtle) {
    // セキュアコンテキスト - crypto.subtleを使用
    return await sha256(Math.random().toString(36).substring(2, 10));
    } else {
    // 開発用のフォールバック(本番環境では安全ではありません)
    console.warn('Using fallback nonce - not secure for production');
    return btoa(Math.random().toString(36).substring(2, 10));
    }
    }

最近のFirebaseドキュメントでは、ログイン設定に関係なく、Facebook認証にnonceを含むJWT tokenが必要です。このアプローチはlimitedLogin: truelimitedLogin: falseの両方で機能します:

// 両方のモードは、ユーザーの選択に応じてJWT tokenを返すことができます
const loginResult = await SocialLogin.login({
provider: 'facebook',
options: {
permissions: ['email', 'public_profile'],
limitedLogin: false, // true = 常にJWT、false = ユーザーのトラッキング選択に依存
nonce: nonce
}
});

開発の制限: ネットワークIP(localhostではない)でionic serveを使用している場合、crypto APIの制限によりFacebookログインは失敗します。WebテストにはlocalhostまたはHTTPSを使用してください。

  1. Androidのkey hashエラー

    • Facebookダッシュボードに正しいkey hashを追加したことを再確認してください
    • リリースビルドの場合は、デバッグとリリースの両方のkey hashを追加したことを確認してください
    • hashを生成する際に正しいkeystoreを使用していることを確認してください
  2. Facebookログインボタンが表示されない

    • すべてのマニフェストエントリが正しいことを確認してください
    • Facebook App IDとClient Tokenが正しいことを確認してください
    • SDKを適切に初期化したことを確認してください
  3. iOSのよくある問題

    • すべてのInfo.plistエントリが正しいことを確認してください
    • URL schemesが適切に設定されていることを確認してください
    • bundle IDがFacebookダッシュボードに登録されているものと一致することを確認してください
  1. テスト前に、Facebook Developer Consoleでテストユーザーを追加してください

    • Roles > Test Usersに移動します
    • テストユーザーを作成します
    • これらの資格情報をテストに使用します
  2. デバッグビルドとリリースビルドの両方をテストしてください

    • デバッグkey hashを使用したデバッグビルド
    • リリースkey hashを使用したリリースビルド
    • エミュレータと実機の両方でテスト

次を含む完全なログインフローをテストすることを忘れないでください:

  • ログイン成功
  • ログインキャンセル
  • エラー処理
  • ログアウト機能