Apple と Unity を使用して認証する

Firebase SDK を使用してエンドツーエンドの OAuth 2.0 ログインフローを実行すると、ユーザーが Firebase での認証に Apple ID を使用できるようになります。

始める前に

ユーザーが Apple を使用してログインできるようにするには、まず Apple のデベロッパー サイトで「Apple でサインイン」を構成してから、Firebase プロジェクトのログイン プロバイダとして Apple を有効にします。

Apple Developer Program に参加する

「Apple でサインイン」は Apple Developer Program のメンバーのみが構成できます。

「Apple でサインイン」を構成する

Firebase プロジェクトで Apple サインインを有効にし、適切に構成する必要があります。Apple Developer の構成は、Android と Apple のプラット フォームによって異なります。先に進む前に、iOS+ および / または Androidガイドの「「Apple でサインイン」を構成する」セクションの内容に沿って構成してください。

Apple をログイン プロバイダとして有効にする

  1. Firebase コンソールで [Authentication] セクションを開きます。[Sign-in method] タブで、[Apple] プロバイダを有効にします。
  2. Apple サインインのプロバイダ設定を構成します。
    1. Apple プラットフォームのみでアプリをデプロイする場合は、[サービス ID]、[Apple チーム ID]、[秘密鍵]、[キー ID] のフィールドを空欄にしておけます。
    2. Android デバイスでのサポート:
      1. Firebase を Android プロジェクトに追加します。Firebase コンソールでアプリを設定する際は、必ずアプリの SHA-1 署名を登録してください。
      2. Firebase コンソールで [Authentication] セクションを開きます。[Sign-in method] タブで、[Apple] プロバイダを有効にします。前のセクションで作成したサービス ID を指定します。また、[OAuth コードフローの構成] セクションで、Apple チーム ID、前のセクションで作成した秘密鍵とキー ID を指定します。

Apple の匿名化データの要件を遵守する

「Apple でサインイン」には、ユーザーがログイン時に、メールアドレスを含む自分のデータを匿名化できるオプションがあります。このオプションを選択したユーザーには、ドメイン privaterelay.appleid.com のメールアドレスが作成されます。アプリで「Apple でサインイン」を使用する場合は、これらの匿名化された Apple ID に関して、Apple が定めるデベロッパー ポリシーと利用規約を遵守する必要があります。

これには、本人を直接特定できる個人情報を、匿名化された Apple ID に関連付ける前に、必要なユーザーの同意を得ることも含まれます。Firebase Authentication を使用する場合、この関連付けには、次のアクションが該当することがあります。

  • 匿名化された Apple ID にメールアドレスをリンク(またはその逆方向にリンク)する。
  • 匿名化された Apple ID に電話番号をリンク(またはその逆方向にリンク)する。
  • 匿名化された Apple ID に匿名ではないソーシャル認証情報(Facebook、Google など)をリンク(またはその逆方向にリンク)する。

上記のリストはすべてを網羅しているわけではありません。アプリが Apple の要件を満たしていることを確認するには、デベロッパー アカウントの [Membership] セクションにある Apple Developer Program License Agreement をご覧ください。

Firebase.Auth.FirebaseAuth クラスへのアクセス

すべての API 呼び出しは FirebaseAuth クラスを使用して行われます。このクラスには、FirebaseAuth.DefaultInstance を介してアクセスできます。
Firebase.Auth.FirebaseAuth auth = Firebase.Auth.FirebaseAuth.DefaultInstance;

Firebase SDK を使用したログインフローの処理

「Apple でサインイン」を使用してログインするプロセスは、Apple と Android のプラット フォームによって異なります。

Apple プラットフォームの場合

  1. ノンスやトークン生成での Apple サインインを処理するには、Unity の「Apple でサインイン」アセット ストレージ パッケージのような、サードパーティのプラグインをインストールします。 生成されたランダムなノンス文字列(Firebase オペレーションで使用する元の文字列の状態)を検査するには、コードを変更する必要が生じる場合があります(この場合、ノンスの SHA256 ダイジェスト形式の作成前にそのコピーを保存します)。

  2. 生成されたトークン文字列と元のノンスを使用して Firebase 認証情報を作成し、Firebase にログインします。

    Firebase.Auth.Credential credential =
        Firebase.Auth.OAuthProvider.GetCredential("apple.com", appleIdToken, rawNonce, null);
    auth.SignInAndRetrieveDataWithCredentialAsync(credential).ContinueWith(task => {
      if (task.IsCanceled) {
        Debug.LogError("SignInAndRetrieveDataWithCredentialAsync was canceled.");
        return;
      }
      if (task.IsFaulted) {
        Debug.LogError("SignInAndRetrieveDataWithCredentialAsync encountered an error: " + task.Exception);
        return;
      }
    
      Firebase.Auth.AuthResult result = task.Result;
      Debug.LogFormat("User signed in successfully: {0} ({1})",
          result.User.DisplayName, result.User.UserId);
    });
    

  3. 同じパターンを ReauthenticateAsync でも使用できます。これは、ログインしてから短時間のうちに行うことが求められる機密性の高いオペレーションのための、最新の認証情報の取得に使用できます。詳細については、ユーザーを管理するをご覧ください。

  4. Apple プラットフォームで Apple サインインとリンクすると、既存の Firebase アカウントがすでに Apple アカウントにリンクされているというエラーが発生する場合があります。このエラーが発生すると、標準の Firebase.FirebaseException ではなく Firebase.Auth.FirebaseAccountLinkException がスローされます。この場合の例外としては UserInfo.UpdatedCredential プロパティがあります。このプロパティは、有効な場合、FirebaseAuth.SignInAndRetrieveDataWithCredentialAsync で Apple にリンクされたユーザーのログインに使用できます。更新された認証情報により、ログイン オペレーション用にノンスを使用して新しい Apple サインイン トークンを生成する必要がなくなります。

    auth.CurrentUser.LinkWithCredentialAsync(
      Firebase.Auth.OAuthProvider.GetCredential("apple.com", idToken, rawNonce, null))
        .ContinueWithOnMainThread( task => {
          if (task.IsCompletedSuccessfully) {
            // Link Success
          } else {
            if (task.Exception != null) {
              foreach (Exception exception in task.Exception.Flatten().InnerExceptions) {
                Firebase.Auth.FirebaseAccountLinkException firebaseEx =
                  exception as Firebase.Auth.FirebaseAccountLinkException;
                if (firebaseEx != null && firebaseEx.UserInfo.UpdatedCredential.IsValid()) {
                  // Attempt to sign in with the updated credential.
                  auth.SignInAndRetrieveDataWithCredentialAsync(firebaseEx.UserInfo.UpdatedCredential).
                    ContinueWithOnMainThread( authResultTask => {
                      // Handle Auth result.
                    });
                } else {
                  Debug.Log("Link with Apple failed:" + firebaseEx );
                }
              } // end for loop
            }
          }
        });
    

Android の場合

Android では、Firebase SDK を使用してウェブベースの汎用 OAuth ログインをアプリに統合し、エンドツー エンドのログインフローを実行して、Firebase でユーザーを認証します。

Firebase SDK でログインフローを処理する手順は次のとおりです。

  1. Apple に適したプロバイダ ID で構成された FederatedOAuthProviderData のインスタンスを作成します。

    Firebase.Auth.FederatedOAuthProviderData providerData =
      new Firebase.Auth.FederatedOAuthProviderData();
    
    providerData.ProviderId = "apple.com";
    
  2. 省略可: 認証プロバイダにリクエストする、デフォルトを超える追加の OAuth 2.0 スコープを指定します。

    providerData.Scopes = new List<string>();
    providerData.Scopes.Add("email");
    providerData.Scopes.Add("name");
    
  3. 省略可: Apple のログイン画面を英語以外の言語で表示する場合は、locale パラメータを設定します。サポートされる言語 / 地域については、「Apple でサインイン」に関するドキュメントをご覧ください。

    providerData.CustomParameters = new Dictionary<string,string>;
    
    // Localize to French.
    providerData.CustomParameters.Add("language", "fr");
    
  4. プロバイダのデータを構成したら、それを使用して FederatedOAuthProvider を作成します。

    // Construct a FederatedOAuthProvider for use in Auth methods.
    Firebase.Auth.FederatedOAuthProvider provider =
      new Firebase.Auth.FederatedOAuthProvider();
    provider.SetProviderData(providerData);
    
  5. Auth プロバイダ オブジェクトを使用して Firebase での認証を行います。こうすると、他の FirebaseAuth オペレーションとは異なり、ユーザーが認証情報を入力できるウェブビューをポップアップ表示して UI を制御することになります。

    ログインフローを開始するには、signInWithProvider を呼び出します。

    auth.SignInWithProviderAsync(provider).ContinueOnMainThread(task => {
        if (task.IsCanceled) {
            Debug.LogError("SignInWithProviderAsync was canceled.");
            return;
        }
        if (task.IsFaulted) {
            Debug.LogError("SignInWithProviderAsync encountered an error: " +
              task.Exception);
            return;
        }
    
        Firebase.Auth.AuthResult authResult = task.Result;
        Firebase.Auth.FirebaseUser user = authResult.User;
        Debug.LogFormat("User signed in successfully: {0} ({1})",
            user.DisplayName, user.UserId);
    });
    
  6. 同じパターンを ReauthenticateWithProvider でも使用できます。これは、ログインしてから短時間のうちに行うべき機密性の高いオペレーションのために、最新の認証情報を取得するのに使われます。

    user.ReauthenticateWithProviderAsync(provider).ContinueOnMainThread(task => {
        if (task.IsCanceled) {
            Debug.LogError("ReauthenticateWithProviderAsync was canceled.");
            return;
        }
        if (task.IsFaulted) {
            Debug.LogError(
            "ReauthenticateWithProviderAsync encountered an error: " +
                task.Exception);
            return;
        }
    
        Firebase.Auth.AuthResult authResult = task.Result;
        Firebase.Auth.FirebaseUser user = authResult.User;
        Debug.LogFormat("User reauthenticated successfully: {0} ({1})",
            user.DisplayName, user.UserId);
    });
    
  7. また、LinkWithCredentialAsync() を使用して、複数の ID プロバイダを既存のアカウントにリンクできます。

    Apple は、Apple アカウントを他のデータにリンクする前にユーザーから明示的な同意を得ることを要件としています。

    たとえば、Facebook アカウントを現在の Firebase アカウントにリンクさせるには、ユーザーの Facebook へのログイン時に取得したアクセス トークンを使用します。

    // Initialize a Facebook credential with a Facebook access token.
    
    Firebase.Auth.Credential credential =
        Firebase.Auth.FacebookAuthProvider.GetCredential(facebook_token);
    
    // Assuming the current user is an Apple user linking a Facebook provider.
    user.LinkWithCredentialAsync(credential)
        .ContinueWithOnMainThread( task => {
          if (task.IsCanceled) {
              Debug.LogError("LinkWithCredentialAsync was canceled.");
              return;
          }
          if (task.IsFaulted) {
            Debug.LogError("LinkWithCredentialAsync encountered an error: "
                           + task.Exception);
              return;
          }
    
          Firebase.Auth.AuthResult result = task.Result;
          Firebase.Auth.FirebaseUser user = result.User;
          Debug.LogFormat("User linked successfully: {0} ({1})",
              user.DisplayName, user.UserId);
        });
    

Apple Notes でログイン

Firebase Auth でサポートされている他のプロバイダとは異なり、Apple では写真の URL が提供されません。

また、ユーザーがアプリとメールの共有を行わない場合、Apple はそのユーザーに固有のメールアドレス(xyz@privaterelay.appleid.com の形式)をプロビジョニングし、これがアプリと共有されます。プライベート メールリレー サービスを構成した場合、Apple は、匿名化されたアドレスに送信されたメールを、ユーザーの実際のメールアドレスに転送します。

Apple が表示名などのユーザー情報をアプリと共有するのは、ユーザーの初回ログイン時のみです。通常、ユーザーが初めて Apple でログインしたときに Firebase で表示名が保存されます。この情報は auth.CurrentUser.DisplayName で取得できます。ただし、以前に Apple でアプリへのユーザーのログインを行った際に Firebase を使用していなかった場合、Apple はユーザーの表示名を Firebase に提供しません。

次のステップ

ユーザーが初めてログインすると、新しいユーザー アカウントが作成され、ユーザーがログインに使用した認証情報(ユーザー名とパスワード、電話番号、または認証プロバイダ情報)にアカウントがリンクされます。この新しいアカウントは Firebase プロジェクトの一部として保存され、ユーザーのログイン方法にかかわらず、プロジェクトのすべてのアプリでユーザーを識別するために使用できます。

アプリでは、Firebase.Auth.FirebaseUser オブジェクトからユーザーの基本的なプロフィール情報を取得できます。ユーザーの管理についての記事をご覧ください。

Firebase Realtime Database と Cloud Storage のセキュリティ ルールでは、ログイン済みユーザーの一意の ユーザー ID を auth 変数から取得し、それを使用して、ユーザーがアクセス可能なデータを制御できます。