Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

JavaScriptでAppleを使用して認証する

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

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

あなたが始める前に

Apple を使用してユーザーをサインインするには、まず Apple の開発者サイトで Sign In with Apple を構成してから、Firebase プロジェクトのサインイン プロバイダーとして Apple を有効にします。

Apple デベロッパ プログラムに参加する

Sign In with Apple は、 Apple Developer Programのメンバーのみが構成できます。

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

Apple Developerサイトで、次の操作を行います。

  1. Web 用に Apple でサインインを構成する の最初のセクションで説明されているように、Web サイトをアプリに関連付けます。プロンプトが表示されたら、次の URL をリターン URL として登録します。

    https://YOUR_FIREBASE_PROJECT_ID.firebaseapp.com/__/auth/handler

    Firebase コンソールの設定ページで Firebase プロジェクト ID を取得できます。

    完了したら、次のセクションで必要になる新しいサービス ID をメモします。

  2. Sign In with Apple private key を作成します。次のセクションで、新しい秘密鍵とキー ID が必要になります。
  3. メール リンクのサインイン、メール アドレスの確認、アカウント変更の取り消しなど、ユーザーにメールを送信する Firebase Authentication の機能のいずれかを使用する場合は、Apple プライベート メール リレー サービスを構成し、 noreply@ YOUR_FIREBASE_PROJECT_ID .firebaseapp.com (またはカスタマイズしたメール テンプレート ドメイン)を使用して、Apple が Firebase Authentication から送信されたメールを匿名の Apple メール アドレスにリレーできるようにします。

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

  1. プロジェクトに Firebase を追加します
  2. Firebase コンソールで、 Authセクションを開きます。 [サインイン方法] タブで、 Appleプロバイダーを有効にします。前のセクションで作成したサービス ID を指定します。また、 OAuth コード フロー構成セクションで、Apple チーム ID と、前のセクションで作成した秘密鍵と鍵 ID を指定します。

Apple の匿名データ要件に準拠する

Sign In with Apple では、ユーザーはサインイン時にメール アドレスなどのデータを匿名化するオプションを利用できます。このオプションを選択したユーザーは、ドメインがprivaterelay.appleid.comのメール アドレスを持っています。アプリで Sign In with Apple を使用する場合、これらの匿名化された Apple ID に関して適用される開発者ポリシーまたは Apple の条件に従う必要があります。

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

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

上記のリストは網羅的なものではありません。アプリが Apple の要件を満たしていることを確認するには、開発者アカウントのメンバーシップ セクションにある Apple Developer Program License Agreement を参照してください。

Firebase SDK でログイン フローを処理する

Web アプリを構築している場合、Apple アカウントを使用して Firebase でユーザーを認証する最も簡単な方法は、Firebase JavaScript SDK を使用してログイン フロー全体を処理することです。

Firebase JavaScript SDK でサインイン フローを処理するには、次の手順に従います。

  1. 対応するプロバイダー ID apple.comを使用してOAuthProviderのインスタンスを作成します。

    Web version 9

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('apple.com');

    Web version 8

    var provider = new firebase.auth.OAuthProvider('apple.com');
  2. オプション:認証プロバイダーから要求するデフォルト以外の追加の OAuth 2.0 スコープを指定します。

    Web version 9

    provider.addScope('email');
    provider.addScope('name');

    Web version 8

    provider.addScope('email');
    provider.addScope('name');

    デフォルトでは、メール アドレスごとに 1 つのアカウントが有効になっている場合、Firebase はメールと名前のスコープをリクエストします。この設定を [電子メール アドレスごとに複数のアカウント] に変更すると、指定しない限り、Firebase は Apple にスコープを要求しません。

  3. オプション: Apple のサインイン画面を英語以外の言語で表示する場合は、 localeパラメーターを設定します。サポートされているロケールについては、 Apple でサインインに関するドキュメントを参照してください。

    Web version 9

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });

    Web version 8

    provider.setCustomParameters({
      // Localize the Apple authentication screen in French.
      locale: 'fr'
    });
  4. OAuth プロバイダー オブジェクトを使用して Firebase で認証します。ポップアップ ウィンドウを開くか、サインイン ページにリダイレクトすることで、Apple アカウントでサインインするようにユーザーに促すことができます。モバイル デバイスではリダイレクト方式が推奨されます。

    • ポップアップ ウィンドウでサインインするには、 signInWithPopup()を呼び出します。

      Web version 9

      import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      signInWithPopup(auth, provider)
        .then((result) => {
          // The signed-in user info.
          const user = result.user;
      
          // Apple credential
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
      
          // ...
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

      Web version 8

      firebase
        .auth()
        .signInWithPopup(provider)
        .then((result) => {
          /** @type {firebase.auth.OAuthCredential} */
          var credential = result.credential;
      
          // The signed-in user info.
          var user = result.user;
      
          // You can also get the Apple OAuth Access and ID Tokens.
          var accessToken = credential.accessToken;
          var idToken = credential.idToken;
      
          // ...
        })
        .catch((error) => {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
      
          // ...
        });
    • サインイン ページにリダイレクトしてサインインするには、 signInWithRedirect()を呼び出します。

      Web version 9

      import { getAuth, signInWithRedirect } from "firebase/auth";
      
      const auth = getAuth();
      signInWithRedirect(auth, provider);

      Web version 8

      firebase.auth().signInWithRedirect(provider);

      ユーザーがサインインを完了してページに戻った後、 getRedirectResult()を呼び出してサインイン結果を取得できます。

      Web version 9

      import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
      
      // Result from Redirect auth flow.
      const auth = getAuth();
      getRedirectResult(auth)
        .then((result) => {
          const credential = OAuthProvider.credentialFromResult(result);
          if (credential) {
            // You can also get the Apple OAuth Access and ID Tokens.
            const accessToken = credential.accessToken;
            const idToken = credential.idToken;
          }
          // The signed-in user info.
          const user = result.user;
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The credential that was used.
          const credential = OAuthProvider.credentialFromError(error);
      
          // ...
        });

      Web version 8

      // Result from Redirect auth flow.
      firebase
        .auth()
        .getRedirectResult()
        .then((result) => {
          if (result.credential) {
            /** @type {firebase.auth.OAuthCredential} */
            var credential = result.credential;
      
            // You can get the Apple OAuth Access and ID Tokens.
            var accessToken = credential.accessToken;
            var idToken = credential.idToken;
      
            // ...
          }
          // The signed-in user info.
          var user = result.user;
        })
        .catch((error) => {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          // The email of the user's account used.
          var email = error.email;
          // The firebase.auth.AuthCredential type that was used.
          var credential = error.credential;
      
          // ...
        });

      これは、エラーをキャッチして処理できる場所でもあります。エラー コードの一覧については、 API リファレンスを参照してください。

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

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

    Apple は、ユーザーが初めてサインインしたときにのみ、表示名などのユーザー情報をアプリと共有します。通常、Firebase は、ユーザーが Apple に初めてサインインしたときに表示名を保存します。これは、 firebase.auth().currentUser.displayName .ただし、以前に Apple を使用して Firebase を使用せずにユーザーをアプリにサインインさせた場合、Apple は Firebase にユーザーの表示名を提供しません。

再認証とアカウントのリンク

同じパターンをreauthenticateWithPopup()reauthenticateWithRedirect()で使用できます。これを使用して、最近のサインインが必要な機密操作の新しい資格情報を取得できます。

Web version 9

import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth";

// Result from Redirect auth flow.
const auth = getAuth();
const provider = new OAuthProvider('apple.com');

reauthenticateWithPopup(auth.currentUser, provider)
  .then((result) => {
    // User is re-authenticated with fresh tokens minted and can perform
    // sensitive operations like account deletion, or updating their email
    // address or password.

    // The signed-in user info.
    const user = result.user;

    // You can also get the Apple OAuth Access and ID Tokens.
    const credential = OAuthProvider.credentialFromResult(result);
    const accessToken = credential.accessToken;
    const idToken = credential.idToken;

    // ...
  })
  .catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
    // The email of the user's account used.
    const email = error.customData.email;
    // The credential that was used.
    const credential = OAuthProvider.credentialFromError(error);

    // ...
  });

Web version 8

const provider = new firebase.auth.OAuthProvider('apple.com');

firebase
  .auth()
  .currentUser
  .reauthenticateWithPopup(provider)
  .then((result) => {
    // User is re-authenticated with fresh tokens minted and can perform
    // sensitive operations like account deletion, or updating their email
    // address or password.
    /** @type {firebase.auth.OAuthCredential} */
    var credential = result.credential;

    // The signed-in user info.
    var user = result.user;
     // You can also get the Apple OAuth Access and ID Tokens.
    var accessToken = credential.accessToken;
    var idToken = credential.idToken;

    // ...
  })
  .catch((error) => {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // The email of the user's account used.
    var email = error.email;
    // The firebase.auth.AuthCredential type that was used.
    var credential = error.credential;

    // ...
  });

また、 linkWithPopup()およびlinkWithRedirect() ) を使用して、さまざまな ID プロバイダーを既存のアカウントにリンクできます。

Apple では、Apple アカウントを他のデータにリンクする前に、ユーザーから明示的な同意を得る必要があることに注意してください。

たとえば、Facebook アカウントを現在の Firebase アカウントにリンクするには、ユーザーが Facebook にサインインして取得したアクセス トークンを使用します。

Web version 9

import { getAuth, linkWithPopup, FacebookAuthProvider } from "firebase/auth";

const auth = getAuth();
const provider = new FacebookAuthProvider();
provider.addScope('user_birthday');

// Assuming the current user is an Apple user linking a Facebook provider.
linkWithPopup(auth.currentUser, provider)
    .then((result) => {
      // Facebook credential is linked to the current Apple user.
      // ...

      // The user can now sign in to the same account
      // with either Apple or Facebook.
    })
    .catch((error) => {
      // Handle error.
    });

Web version 8

const provider = new firebase.auth.FacebookAuthProvider();
provider.addScope('user_birthday');

// Assuming the current user is an Apple user linking a Facebook provider.
firebase.auth().currentUser.linkWithPopup(provider)
    .then((result) => {
      // Facebook credential is linked to the current Apple user.
      // Facebook additional data available in result.additionalUserInfo.profile,

      // Additional Facebook OAuth access token can also be retrieved.
      // result.credential.accessToken

      // The user can now sign in to the same account
      // with either Apple or Facebook.
    })
    .catch((error) => {
      // Handle error.
    });

Chrome 拡張機能で Firebase を使用して認証する

Chrome 拡張アプリを作成している場合は、Chrome 拡張 ID を追加する必要があります。

  1. Firebase コンソールでプロジェクトを開きます。
  2. [認証]セクションで、[サインイン方法] ページを開きます。
  3. 次のような URI を承認済みドメインのリストに追加します:
    chrome-extension://CHROME_EXTENSION_ID

Chrome 拡張機能は HTTP リダイレクトを使用できないため、ポップアップ操作 ( signInWithPopuplinkWithPopup 、およびreauthenticateWithPopup ) のみが Chrome 拡張機能で使用できます。認証ポップアップはブラウザ アクション ポップアップをキャンセルするため、ブラウザ アクション ポップアップではなく、バックグラウンド ページ スクリプトからこれらのメソッドを呼び出す必要があります。 popup メソッドは、 Manifest V2を使用する拡張機能でのみ使用できます。新しいマニフェスト V3では、ポップアップ操作をまったく実行できない Service Worker の形式のバックグラウンド スクリプトのみが許可されます。

Chrome 拡張機能のマニフェスト ファイルで、必ずhttps://apis.google.com URL をcontent_security_policy許可リストに追加してください。

デフォルトの firebaseapp.com ドメインと同様に、Apple でカスタム ドメインを検証する必要があることに注意してください。

http://auth.custom.example.com/.well-known/apple-developer-domain-association.txt

高度: Node.js で Firebase を使用して認証する

Node.js アプリケーションで Firebase で認証するには:

  1. Apple アカウントでユーザーにサインインし、ユーザーの Apple ID トークンを取得します。これはいくつかの方法で実現できます。たとえば、Node.js アプリにブラウザー フロント エンドがある場合:

    1. バックエンドで、ランダムな文字列 (「ノンス」) を生成し、その SHA256 ハッシュを計算します。 nonce は、バックエンドと Apple の認証サーバー間の 1 回の往復を検証するために使用する 1 回限りの値です。

      Web version 9

      const crypto = require("crypto");
      const string_decoder = require("string_decoder");
      
      // Generate a new random string for each sign-in
      const generateNonce = (length) => {
        const decoder = new string_decoder.StringDecoder("ascii");
        const buf = Buffer.alloc(length);
        let nonce = "";
        while (nonce.length < length) {
          crypto.randomFillSync(buf);
          nonce = decoder.write(buf);
        }
        return nonce.slice(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');

      Web version 8

      const crypto = require("crypto");
      const string_decoder = require("string_decoder");
      
      // Generate a new random string for each sign-in
      const generateNonce = function(length) {
        const decoder = new string_decoder.StringDecoder("ascii");
        const buf = Buffer.alloc(length);
        var nonce = "";
        while (nonce.length < length) {
          crypto.randomFillSync(buf);
          nonce = decoder.write(buf);
        }
        return nonce.slice(0, length);
      };
      
      const unhashedNonce = generateNonce(10);
      
      // SHA256-hashed nonce in hex
      const hashedNonceHex = crypto.createHash('sha256')
        .update(unhashedNonce).digest().toString('hex');
    2. サインイン ページで、Sign In with Apple 構成でハッシュされた nonce を指定します。

      <script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"></script>
      <div id="appleid-signin" data-color="black" data-border="true" data-type="sign in"></div>
      <script>
          AppleID.auth.init({
              clientId: YOUR_APPLE_CLIENT_ID,
              scope: 'name email',
              redirectURI: URL_TO_YOUR_REDIRECT_HANDLER,  // See the next step.
              state: '[STATE]',  // Optional value that Apple will send back to you
                                 // so you can return users to the same context after
                                 // they sign in.
              nonce: HASHED_NONCE  // The hashed nonce you generated in the previous step.
          });
      </script>
      
    3. POSTed 認証応答サーバー側から Apple ID トークンを取得します。

      app.post('/redirect', (req, res) => {
        const savedState = req.cookies.__session;
        const code = req.body.code;
        const state = req.body.state;
        const appleIdToken = req.body.id_token;
        if (savedState !== state || !code) {
          res.status(403).send('403: Permission denied');
        } else {
          // Sign in with Firebase using appleIdToken. (See next step).
        }
      });
      

    Apple でサインインするための Web ページの設定も参照してください。

  2. ユーザーの Apple ID トークンを取得したら、それを使用して Credential オブジェクトを作成し、資格情報を使用してユーザーをサインインさせます。

    Web version 9

    import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    
    // Build Firebase credential with the Apple ID token.
    const provider = new OAuthProvider('apple.com');
    const authCredential = provider.credential({
      idToken: appleIdToken,
      rawNonce: unhashedNonce,
    });
    
    // Sign in with credential form the Apple user.
    signInWithCredential(auth, authCredential)
      .then((result) => {
        // User signed in.
      })
      .catch((error) => {
        // An error occurred. If error.code == 'auth/missing-or-invalid-nonce',
        // make sure you're sending the SHA256-hashed nonce as a hex string
        // with your request to Apple.
        console.log(error);
      });

    Web version 8

    // Build Firebase credential with the Apple ID token.
    const provider = new firebase.auth.OAuthProvider('apple.com');
    const authCredential = provider.credential({
      idToken: appleIdToken,
      rawNonce: unhashedNonce,
    });
    
    // Sign in with credential form the Apple user.
    firebase.auth().signInWithCredential(authCredential)
      .then((result) => {
        // User signed in.
      })
      .catch((error) => {
        // An error occurred. If error.code == 'auth/missing-or-invalid-nonce',
        // make sure you're sending the SHA256-hashed nonce as a hex string
        // with your request to Apple.
        console.log(error);
      });

次のステップ

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

  • アプリでユーザーの認証ステータスを知るための推奨される方法は、 Authオブジェクトにオブザーバーを設定することです。その後、 Userオブジェクトからユーザーの基本的なプロファイル情報を取得できます。ユーザーの管理を参照してください。

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

認証プロバイダーの資格情報を既存のユーザー アカウントにリンクすることで、ユーザーが複数の認証プロバイダーを使用してアプリにサインインできるようにすることができます。

ユーザーをサインアウトするには、 signOutを呼び出します。

Web version 9

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web version 8

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});