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

JavaScriptを使用して電話番号でFirebaseで認証する

SMS メッセージをユーザーの電話に送信することで、Firebase Authentication を使用してユーザーをサインインさせることができます。ユーザーは、SMS メッセージに含まれるワンタイム コードを使用してサインインします。

アプリに電話番号サインインを追加する最も簡単な方法は、 FirebaseUIを使用することです。これには、電話番号サインインのサインイン フローを実装するドロップイン サインイン ウィジェットと、パスワード ベースのフェデレーション サインが含まれています。 -の。このドキュメントでは、Firebase SDK を使用して電話番号ログイン フローを実装する方法について説明します。

あなたが始める前に

まだ行っていない場合は、 Firebase を JavaScript プロジェクトに追加する の説明に従って、初期化スニペットをFirebase コンソールからプロジェクトにコピーします。

セキュリティ上の懸念

電話番号のみを使用した認証は便利ですが、電話番号の所有権がユーザー間で簡単に譲渡される可能性があるため、他の使用可能な方法よりも安全性が低くなります。また、複数のユーザー プロファイルを持つデバイスでは、SMS メッセージを受信できるユーザーは、デバイスの電話番号を使用してアカウントにサインインできます。

アプリで電話番号ベースのサインインを使用する場合は、より安全なサインイン方法と一緒に提供し、電話番号によるサインインの使用によるセキュリティのトレードオフについてユーザーに通知する必要があります。

Firebase プロジェクトの電話番号ログインを有効にする

ユーザーを SMS でサインインするには、最初に Firebase プロジェクトで電話番号によるサインイン方法を有効にする必要があります。

  1. Firebase コンソールで、[認証]セクションを開きます。
  2. [サインイン方法]ページで、電話番号によるサインイン方法を有効にします。
  3. 同じページで、アプリをホストするドメインがOAuth リダイレクト ドメインセクションにリストされていない場合は、ドメインを追加します。

Firebase の電話番号サインイン リクエスト クォータは十分に高いため、ほとんどのアプリは影響を受けません。ただし、電話認証を使用して大量のユーザーをサインインさせる必要がある場合は、料金プランのアップグレードが必要になる場合があります。料金ページをご覧ください。

reCAPTCHA ベリファイアを設定する

ユーザーが電話番号でサインインする前に、Firebase の reCAPTCHA ベリファイアを設定する必要があります。 Firebase は reCAPTCHA を使用して、電話番号の確認リクエストがアプリの許可されたドメインのいずれかから送信されるようにするなど、不正使用を防止します。

reCAPTCHA クライアントを手動で設定する必要はありません。 Firebase SDK のRecaptchaVerifierオブジェクトを使用すると、Firebase は必要なクライアント キーとシークレットを自動的に作成して処理します。

RecaptchaVerifierオブジェクトは、多くの場合、ユーザーのアクションを必要とせずにユーザーを検証できる非表示のreCAPTCHAと、正常に完了するために常にユーザーの操作を必要とする reCAPTCHA ウィジェットをサポートしています。

基になるレンダリングされた reCAPTCHA は、reCAPTCHA をレンダリングする前に Auth インスタンスの言語コードを更新することで、ユーザーの好みに合わせてローカライズできます。前述のローカライズは、確認コードを含む、ユーザーに送信される SMS メッセージにも適用されます。

Web version 9

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Web version 8

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

非表示の reCAPTCHA を使用する

非表示の reCAPTCHA を使用するには、 sizeパラメーターをinvisibleに設定してRecaptchaVerifierオブジェクトを作成し、サインイン フォームを送信するボタンの ID を指定します。例えば:

Web version 9

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

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
}, auth);

Web version 8

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

reCAPTCHA ウィジェットを使用する

可視の reCAPTCHA ウィジェットを使用するには、ウィジェットを含める要素をページに作成してから、コンテナの ID を指定してRecaptchaVerifierオブジェクトを作成します。例えば:

Web version 9

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

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {}, auth);

Web version 8

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

オプション: reCAPTCHA パラメーターを指定する

オプションで、ユーザーが reCAPTCHA を解決したとき、またはユーザーがフォームを送信する前に reCAPTCHA が期限切れになったときに呼び出されるコールバック関数をRecaptchaVerifierオブジェクトに設定できます。

Web version 9

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

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
}, auth);

Web version 8

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

オプション: reCAPTCHA を事前にレンダリングする

サインイン リクエストを送信する前に reCAPTCHA を事前にレンダリングする場合は、 renderを呼び出します。

Web version 9

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web version 8

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

renderが解決したら、reCAPTCHA のウィジェット ID を取得します。これを使用して、 reCAPTCHA API を呼び出すことができます。

Web version 9

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web version 8

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

ユーザーの電話に確認コードを送信する

電話番号によるサインインを開始するには、電話番号の入力を求めるインターフェースをユーザーに提示し、 signInWithPhoneNumberを呼び出して、Firebase がユーザーの電話に SMS で認証コードを送信するように要求します。

  1. ユーザーの電話番号を取得します。

    法的要件はさまざまですが、ベスト プラクティスとして、またユーザーの期待を設定するために、ユーザーが電話によるサインインを使用する場合、確認のために SMS メッセージを受信する可能性があり、標準料金が適用されることをユーザーに通知する必要があります。

  2. signInWithPhoneNumberを呼び出し、ユーザーの電話番号と前に作成したRecaptchaVerifierを渡します。

    Web version 9

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web version 8

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    signInWithPhoneNumberでエラーが発生した場合は、ユーザーが再試行できるように reCAPTCHA をリセットします:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

signInWithPhoneNumberメソッドは reCAPTCHA チャレンジをユーザーに発行し、ユーザーがチャレンジに合格すると、Firebase Authentication が確認コードを含む SMS メッセージをユーザーの電話に送信するように要求します。

確認コードを使用してユーザーにサインインします

signInWithPhoneNumberの呼び出しが成功したら、SMS で受け取った確認コードを入力するようユーザーに求めます。次に、 signInWithPhoneNumberのフルフィルメント ハンドラー (つまり、 thenブロック) に渡されたConfirmationResultオブジェクトのconfirmメソッドにコードを渡して、ユーザーをサインインさせます。例えば:

Web version 9

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web version 8

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

confirmの呼び出しが成功した場合、ユーザーは正常にサインインしています。

中間 AuthCredential オブジェクトを取得する

ユーザーのアカウントのAuthCredentialオブジェクトを取得する必要がある場合は、 confirmを呼び出す代わりに、確認結果からの確認コードと確認コードをPhoneAuthProvider.credentialに渡します:

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

次に、資格情報を使用してユーザーにサインインできます。

firebase.auth().signInWithCredential(credential);

架空の電話番号でテストする

Firebase コンソールを介して、開発用の架空の電話番号を設定できます。架空の電話番号を使用したテストには、次の利点があります。

  • 使用クォータを消費せずに電話番号認証をテストします。
  • 実際の SMS メッセージを送信せずに電話番号認証をテストします。
  • 調整されることなく、同じ電話番号で連続してテストを実行します。これにより、レビュー担当者がたまたま同じ電話番号をテストに使用した場合に、App Store のレビュー プロセス中に拒否されるリスクが最小限に抑えられます。
  • Google Play Services を使用せずに iOS シミュレーターや Android エミュレーターで開発する機能など、追加の労力を必要とせずに開発環境で簡単にテストできます。
  • 本番環境で実際の電話番号に通常適用されるセキュリティ チェックによってブロックされることなく、統合テストを記述します。

架空の電話番号は、次の要件を満たす必要があります。

  1. 実際に架空のものであり、まだ存在していない電話番号を使用していることを確認してください。 Firebase Authentication では、実際のユーザーが使用する既存の電話番号をテスト番号として設定することはできません。 1 つのオプションは、555 のプレフィックス番号を米国のテスト用電話番号として使用することです。たとえば、 +1 650-555-3434 です。
  2. 電話番号は、長さやその他の制約に合わせて正しくフォーマットする必要があります。実際のユーザーの電話番号と同じ検証が行われます。
  3. 開発用に最大 10 個の電話番号を追加できます。
  4. 推測しにくいテスト用の電話番号/コードを使用し、頻繁に変更してください。

架空の電話番号と確認コードを作成する

  1. Firebase コンソールで、[認証]セクションを開きます。
  2. [サインイン方法] タブで、電話プロバイダーをまだ有効にしていない場合は有効にします。
  3. アコーディオン メニューをテストするための電話番号を開きます。
  4. テストする電話番号を入力します (例: +1 650-555-3434 )
  5. その特定の番号の 6 桁の確認コードを入力します (例: 654321 )
  6. 番号を追加します。必要に応じて、対応する行にカーソルを合わせてゴミ箱アイコンをクリックすると、電話番号とそのコードを削除できます。

手動テスト

アプリケーションで架空の電話番号の使用を直接開始できます。これにより、割り当ての問題やスロットリングに遭遇することなく、開発段階で手動テストを実行できます。 Google Play サービスがインストールされていない iOS シミュレーターまたは Android エミュレーターから直接テストすることもできます。

架空の電話番号を入力して確認コードを送信すると、実際の SMS は送信されません。代わりに、以前に構成した確認コードを入力してサインインを完了する必要があります。

サインインが完了すると、その電話番号を使用して Firebase ユーザーが作成されます。ユーザーは、実際の電話番号ユーザーと同じ動作とプロパティを持ち、Realtime Database/Cloud Firestore やその他のサービスに同じ方法でアクセスできます。このプロセスで作成された ID トークンには、実際の電話番号ユーザーと同じ署名があります。

別のオプションとして、これらのユーザーにカスタム クレームを介してテスト ロールを設定し、アクセスをさらに制限する場合に偽のユーザーとして区別することもできます。

統合テスト

手動テストに加えて、Firebase Authentication は、電話認証テスト用の統合テストを作成するのに役立つ API を提供します。これらの API は、Web の reCAPTCHA 要件と iOS のサイレント プッシュ通知を無効にすることで、アプリの検証を無効にします。これにより、これらのフローで自動化テストが可能になり、実装が容易になります。さらに、Android で即時確認フローをテストする機能を提供するのに役立ちます。

Web では、 firebase.auth.RecaptchaVerifierをレンダリングする前にappVerificationDisabledForTestingtrueに設定します。これにより、reCAPTCHA が自動的に解決されるため、手動で解決しなくても電話番号を渡すことができます。 reCAPTCHA が無効になっていても、架空の電話番号を使用するとサインインが完了しないことに注意してください。この API で使用できるのは架空の電話番号のみです。

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

アプリの検証が無効になっている場合、可視および不可視のモック reCAPTCHA アプリ検証ツールの動作は異なります。

  • 可視 reCAPTCHA : 可視 reCAPTCHA がappVerifier.render()を介してレンダリングされると、数分の 1 秒の遅延の後に自動的に解決されます。これは、ユーザーがレンダリング直後に reCAPTCHA をクリックするのと同じです。 reCAPTCHA 応答はしばらくすると期限切れになり、その後再び自動解決されます。
  • 目に見えない reCAPTCHA : 目に見えない reCAPTCHA は、レンダリング時に自動解決されず、代わりにappVerifier.verify()の呼び出し時、または reCAPTCHA のボタン アンカーが一瞬遅れてクリックされたときに自動解決されます。同様に、応答はしばらくすると期限切れになり、 appVerifier.verify()呼び出しの後、または reCAPTCHA のボタン アンカーが再度クリックされたときにのみ自動解決されます。

モック reCAPTCHA が解決されるたびに、対応するコールバック関数が偽の応答で期待どおりにトリガーされます。期限切れコールバックも指定されている場合、期限切れでトリガーされます。

次のステップ

ユーザーが初めてサインインすると、新しいユーザー アカウントが作成され、サインインに使用したユーザーの資格情報 (ユーザー名とパスワード、電話番号、または認証プロバイダー情報) にリンクされます。この新しいアカウントは 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.
});