アプリを Authentication エミュレータに接続する

アプリで Authentication エミュレータを使用する前に、Firebase Local Emulator Suite の全体的なワークフローを理解して、Local Emulator Suite をインストールおよび構成し、CLI コマンドを確認しておいてください。

このトピックは、本番環境用の Firebase Authentication ソリューションの開発について理解していることを前提としています。必要に応じて、プラットフォームと認証技術の組み合わせに関するドキュメントをご確認ください。

Authentication エミュレータでできること

Authentication エミュレータは、本番環境の Firebase Authentication にある機能が多数用意されている Firebase Authentication サービスの高精度のローカル エミュレーションを提供します。エミュレータは、Firebase Apple SDK、Firebase Android SDK、Firebase Web SDK と組み合わせることで以下のことが可能になります。

  • メール / パスワード、電話番号 / SMS、SMS 多要素認証、サードパーティ(Google など)の ID プロバイダ認証をテストするために、エミュレートされたユーザー アカウントを作成、更新、管理する
  • エミュレートされたユーザーを表示および編集する
  • カスタム トークン認証システムのプロトタイプを作成する
  • Emulator UI の [ログ] タブで認証関連のメッセージを確認する

Firebase プロジェクトを選択する

Firebase Local Emulator Suite は、1 つの Firebase プロジェクト向けにプロダクトをエミュレートします。

エミュレータを起動する前に CLI の作業ディレクトリで firebase use を実行し、使用するプロジェクトを選択します。または、各エミュレータ コマンドに --project フラグを渡すという方法もあります。

Local Emulator Suite は、実際の Firebase プロジェクトとデモ プロジェクトのエミュレーションに対応しています。

プロジェクト タイプ 特長 エミュレータでの使用
実際

実際の Firebase プロジェクトとは、(通常は Firebase コンソールで)自分で作成および構成したプロジェクトのことです。

実際のプロジェクトには、データベース インスタンス、ストレージ バケット、関数など、その Firebase プロジェクト用にセットアップしたリソースのライブリソースが含まれています。

実際の Firebase プロジェクトを使用する場合、対応しているプロダクトの一部またはすべてに対してエミュレータを実行できます。

エミュレートしていないプロダクトに関しては、アプリとコードはライブリソース(データベース インスタンス、ストレージ バケット、関数など)とやり取りします。

デモ

デモ Firebase プロジェクトには、実際の Firebase 構成がなく、ライブリソースもありません。これらのプロジェクトには通常、Codelab またはその他のチュートリアルを介してアクセスします。

デモ プロジェクトのプロジェクト ID には demo- という接頭辞が付いています。

デモ Firebase プロジェクトを使用する場合、アプリとコードはエミュレータのみとやり取りします。エミュレータが実行されていないリソースとアプリがやり取りしようとすると、コードは失敗します。

可能な限り、デモ プロジェクトを使用することをおすすめします。次のような利点があります。

  • Firebase プロジェクトを作成せずにエミュレータを実行できるため、セットアップが簡単である
  • エミュレートされていない(本番環境の)リソースを誤って呼び出しても、データが変更されたり、使用量がカウントされたり、課金が発生したりする可能性がないため、安全性が高い
  • インターネットにアクセスして SDK 構成をダウンロードする必要がないため、オフラインでも使いやすい

アプリを計測可能にしてエミュレータと通信する

Android、iOS、Web SDK

次のように、Authentication エミュレータとやり取りするようにアプリ内構成またはテストクラスを設定します。

Kotlin+KTX
Firebase.auth.useEmulator("10.0.2.2", 9099)
Java
FirebaseAuth.getInstance().useEmulator("10.0.2.2", 9099);
Swift
Auth.auth().useEmulator(withHost:"127.0.0.1", port:9099)

ウェブ向けのモジュラー API

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

const auth = getAuth();
connectAuthEmulator(auth, "http://127.0.0.1:9099");

ウェブ向けの名前空間方式 API

const auth = firebase.auth();
auth.useEmulator("http://127.0.0.1:9099");

Authentication と Cloud Functions との間または Authentication と Cloud Firestore / Realtime Database の Firebase セキュリティ ルールとの間のインタラクションのプロトタイプを作成してテストするために、追加の設定は必要ありません。Authentication エミュレータが構成され、他のエミュレータが実行されている場合、これらは自動的に連携します。

Admin SDK

FIREBASE_AUTH_EMULATOR_HOST 環境変数が設定されている場合、Firebase Admin SDK は Authentication エミュレータに自動的に接続します。

export FIREBASE_AUTH_EMULATOR_HOST="127.0.0.1:9099"

Cloud Functions エミュレータは Authentication エミュレータを自動的に認識するため、Cloud Functions エミュレータと Authentication エミュレータの統合をテストする場合はこの手順を省略できます。Cloud Functions の Admin SDK では、この環境変数が自動的に設定されます。

環境変数を設定すると、Firebase Admin SDK は、(verifyIdToken メソッドと createSessionCookie メソッドによって)Authentication エミュレータで発行された、署名されていない ID トークンとセッション Cookie を受け取り、ローカルの開発とテストを容易にします。本番環境でこの環境変数を設定しないようにしてください

Admin SDK コードを別の環境で実行されている共有エミュレータに接続する場合は、Firebase CLI で設定したのと同じプロジェクト ID を指定する必要があります。プロジェクト ID を initializeApp に直接渡すか、GCLOUD_PROJECT 環境変数を設定することによって指定できます。

Node.js Admin SDK
admin.initializeApp({ projectId: "your-project-id" });
環境変数
export GCLOUD_PROJECT="your-project-id"

ID トークン

Authentication エミュレータは、セキュリティ上の理由から、署名なしの ID トークンを発行します。このトークンは他の Firebase エミュレータ、または構成されている場合は Firebase Admin SDK によってのみ受け入れられます。したがって、これらのトークンは、本番環境の Firebase サービスまたは本番環境モードで実行されている Firebase Admin SDK によって拒否されます(上述のセットアップ手順がないデフォルトの動作など)。

エミュレータの使用開始

Authentication エミュレータは、Emulator Suite UI を通じて対話型で使用できます。また、ローカル REST インターフェースを通じて非対話型で使用することもできます。以下のセクションでは、対話型のユースケースと非対話型のユースケースについて説明します。

Authentication エミュレータ、REST インターフェース、Emulator Suite UI の使用を開始するには、次のコマンドを実行します。

firebase emulators:start

匿名認証の場合、アプリでプラットフォーム(iOS Androidウェブ)用のログイン ロジックを実行できます。

メール / パスワード認証の場合は、Authentication SDK メソッドを使用してアプリから Authentication エミュレータにユーザー アカウントを追加するか、Emulator Suite UI を使用してプロトタイピングを開始できます。

  1. Emulator Suite UI で、[Authentication] タブをクリックします。
  2. [ユーザーを追加] ボタンをクリックします。
  3. ユーザー アカウント作成ウィザードに従い、メール認証のフィールドに入力します。

作成したテストユーザーを使用すると、プラットフォーム(iOSAndroidウェブ)用の SDK ロジックでアプリにログインとログアウトができるようになります。

メールリンク フローを使用してメール確認またはログインをテストする場合、エミュレータは firebase emulators:start が実行されたターミナルに URL を出力します。

i  To verify the email address customer@ex.com, follow this link:
http://127.0.0.1:9099/emulator/action?mode=verifyEmail&lang=en&oobCode=XYZ123&apiKey=fake-api-key

リンクをブラウザに貼り付けて確認イベントをシミュレートし、確認が成功したかどうかを確かめます。

{
  "authEmulator": {
    "success": "The email has been successfully verified.",
    "email": "customer@example.com"
  }
}

パスワードの再設定をテストする場合、エミュレータは、newPassword パラメータ(必要に応じて変更可能)を含む同様の URL をターミナルに出力します。

http://127.0.0.1:9099/emulator/action?mode=resetPassword&oobCode=XYZ!23&apiKey=fake-api-key&newPassword=YOUR_NEW_PASSWORD

非対話型テスト

Emulator Suite UI やクライアント コードを使用してメール / パスワード ユーザー アカウントを管理するのではなく、REST API を呼び出してユーザー アカウントの作成と削除、帯域外のメール確認コードの取得を行ってエミュレータのメール確認 URL を入力する、テスト設定スクリプトを作成できます。これにより、プラットフォームとテストコードを分離し、非対話型テストを実施できます。

メールとパスワードの非対話型テストフローの場合、一般的なシーケンスは次のようになります。

  1. Authentication の signUp REST エンドポイントでユーザーを作成します。
  2. メールとパスワードを使用してログインし、テストを実行します。
  3. テストに応じて、エミュレータ固有の REST エンドポイントから帯域外で利用可能なメール確認コードを取得します。
  4. エミュレータ固有の REST エンドポイントでユーザー レコードをフラッシュし、データを消去します。

エミュレートされた電話 / SMS 認証

電話認証の場合、Auth エミュレータでは以下の機能に対応していません。

  • reCAPTCHA フローと APN フロー: クライアント SDK がエミュレータと連携するように構成されると、統合テスト(iOSAndroidウェブ)に関する説明と同様に、クライアント SDK でこれらの確認方法が無効になります。
  • Firebase コンソールで事前構成されたコードを使用して電話番号をテストします。

クライアント コードに関しては、電話 / SMS 認証フローは本番環境(iOSAndroidウェブ)に関する説明と同じです。

Emulator Suite UI を使用する場合:

  1. Emulator Suite UI で、[Authentication] タブをクリックします。
  2. [ユーザーを追加] ボタンをクリックします。
  3. ユーザー アカウント作成ウィザードに従い、電話認証のフィールドに入力します。

ただし、電話認証フローでは携帯通信会社への連絡は対象外であり、ローカルテストには適していないため、エミュレータではテキスト メッセージの配信がトリガーされません。エミュレータは、firebase emulators:start を実行したのと同じターミナルに、SMS 経由で送信されたコードを出力します。このコードをアプリに入力することで、ユーザーによるテキスト メッセージの確認をシミュレートできます。

非対話型テスト

非対話型電話認証テストの場合、Authentication エミュレータの REST API を使用して、利用可能な SMS コードを取得します。SMS コードは、フローを開始するたびに異なることに注意してください。

一般的なシーケンスは次のとおりです。

  1. プラットフォーム signInWithPhoneNumber を呼び出して確認プロセスを開始します。
  2. エミュレータ固有の REST エンドポイントを使用して確認コードを取得します。
  3. 通常どおり、確認コードを使用して confirmationResult.confirm(code) を呼び出します。

多要素 SMS

Authentication エミュレータは、iOSAndroidウェブの本番環境で使用可能な SMS 多要素認証(MFA)フローのプロトタイピングとテストに対応しています。

エミュレータにモックユーザーを追加すると、MFA を有効にして、第 2 要素である SMS メッセージの送信先となる 1 つ以上の電話番号を構成できます。メッセージは、firebase emulators:start を実行したターミナルに出力され、REST インターフェースから使用できます。

エミュレートされたサードパーティ ID プロバイダ(IDP)認証

Authentication エミュレータを使用すると、本番環境コードを変更することなく、iOS、Android、ウェブのアプリで多くのサードパーティ認証フローをテストできます。認証フローの例については、アプリで使用できるプロバイダとプラットフォームの組み合わせのドキュメントをご覧ください。

一般的には、Firebase SDK を使用して、次の 2 つの方法のいずれかによって認証できます。

  • アプリでは、サードパーティ IDP プロバイダとのすべてのやり取りを含むプロセス全体を最初から最後まで SDK で処理し、認証情報を取得できます。
  • アプリはサードパーティ プロバイダの SDK を使用してそのプロバイダから認証情報を自動的ではない手段で取得し、その認証情報を Authentication SDK に渡します。

前述のドキュメントへのリンクを再確認し、Firebase SDK による管理と手動での認証情報取得のどちらのフローを使用する場合も、そのフローをよく理解してください。Authentication エミュレータは、どちらの方法のテストにも対応しています。

Firebase SDK に基づく IDP フローのテスト

アプリが Firebase SDK のエンドツーエンド フロー(OAuthProvider など)を Microsoft、GitHub、Yahoo によるログインに使用している場合、Authentication エミュレータは、signinWithPopup または signInWithRedirect メソッドを呼び出すウェブアプリからの認証をテストできるように、対応するログインページのローカル バージョンを提供します。このローカルに提供されるログインページはモバイルアプリでも表示され、プラットフォームの WebView ライブラリによってレンダリングされます。

エミュレータは、フローの進行に沿って、必要に応じてサードパーティの疑似ユーザー アカウントと認証情報を作成します。

手動での認証情報取得による IDP フローのテスト

「手動」のログイン方法でプラットフォームの signInWithCredentials メソッドを呼び出すと、アプリは通常、実際のサードパーティ ログインをリクエストして実際のサードパーティ認証情報を取得します。

エミュレータは、Google ログイン、Apple、さらに JSON Web Token(JWT)として実装された ID トークンを使用するその他のプロバイダで取得した認証情報に対して signInWithCredential 認証のみをサポートしています。アクセス トークン(たとえば、JWT ではなく Facebook または Twitter によって提供されるトークン)はサポートされていません。次のセクションで、代わりのアプローチについて説明します。

非対話型テスト

非対話型テストの一つとして、エミュレータから提供されるログインページでのユーザーのクリックを自動化する方法があります。ウェブアプリの場合は、WebDriver などのコントロール インターフェースを使用します。モバイルの場合は、Espresso や Xcode などのプラットフォームの UI テストツールを使用します。

また、コードを更新して(コードブランチ内などの)signInWithCredential を使用し、実際の認証情報ではなく、アカウントの疑似 ID トークンを使用するトークン認証フローを使用することもできます。

  1. IDP から idToken を取得するコードの部分を書き換えるか、コメントアウトします。これにより、テスト中に実際のユーザー名とパスワードを入力する必要がなくなり、テストは IDP の API 割り当てとレート制限から解放されます。
  2. 別の方法として、signInWithCredential のトークンの代わりにリテラルの JSON 文字列を使用します。Web SDK を使用した場合、コードを次のように変更できます。
firebase.auth().signInWithCredential(firebase.auth.GoogleAuthProvider.credential(
  '{"sub": "abc123", "email": "foo@example.com", "email_verified": true}'
));

このコードをエミュレータで使用すると、Google でメール foo@example.com を使用してユーザーの認証を完了できます。サブフィールドを、任意の文字列に変更できる主キーと考えると、複数のユーザーで仮のログインが可能になります。firebase.auth.GoogleAuthProvider は、たとえば、new firebase.auth.OAuthProvider('yahoo.com') や仮に使用する他のプロバイダ ID に置き換えることができます。

カスタム トークン認証のエミュレート

本番環境の Authentication のドキュメントで説明されているように、Authentication エミュレータは、サポートされているプラットフォームで signInWithCustomToken メソッドの呼び出しを使用して、カスタムの JSON Web Token による認証を処理します。

Authentication エミュレータと本番環境の違い

Firebase Authentication エミュレータは、本番環境プロダクトの多くの機能をシミュレートします。ただし、どのような種類の認証システムでも、複数レベル(デバイス、サードパーティ プロバイダ、Firebase など)でのセキュリティに大きく依存しているため、エミュレータがすべてのフローを正しく再現するのは困難です。

Cloud IAM

Firebase Emulator Suite は、実行において IAM 関連の動作を複製せず、考慮もしません。エミュレータは指定された Firebase セキュリティ ルールに従いますが、IAM が通常使用される状況では(たとえば、Cloud Functions を呼び出すサービス アカウントの設定、つまりは権限の設定)、エミュレータを構成できないため、開発マシンでグローバルに利用できるアカウントが使用されます。これは、ローカル スクリプトを直接実行するのと似た状況です。

モバイル プラットフォームではメールリンク ログインが Firebase Dynamic Links に依存するため、このようなリンクはすべて(モバイル)ウェブ プラットフォームで開かれます。

サードパーティのログイン

サードパーティのログインフローの場合、Firebase Authentication は Twitter や GitHub などのサードパーティ プロバイダから得られる保護された認証情報に依存します。

Google や Apple などの OpenID Connect プロバイダから得られる実際の認証情報は、Authentication エミュレータで受け入れられます。OpenID Connect 以外のプロバイダから得られる認証情報はサポートされていません。

メール / SMS ログイン

本番環境アプリでは、メールと SMS のログインフローで非同期のオペレーションが行われます。このオペレーションでは、ユーザーは受信したメッセージを確認して、ログイン インターフェースにログインコードを入力します。Authentication エミュレータはメールや SMS メッセージを送信しませんが、上記で説明したように、ログインコードを生成し、テストで使用するためにターミナルに出力します。

固定のログインコードでテスト用電話番号を定義する機能(Firebase コンソールを使用すると可能な機能)は、エミュレータでサポートされていません。

カスタム トークン認証

Authentication エミュレータは、カスタム トークンの署名と有効期限を検証しません。そのため、プロトタイピングやテストのシナリオでは、手動で作成したトークンや再利用トークンを無期限で使用できます。

レート制限 / 不正防止対策

Authentication エミュレータは、本番環境のレート制限や不正防止対策の機能を複製しません。

ブロッキング関数

本番環境では、beforeCreate イベントと beforeSignIn イベントの両方がトリガーされた後に、ユーザーはストレージに 1 回書き込まれます。ただし、技術的な制限により、Authentication エミュレータは、ユーザーの作成後とログイン後に 1 回ずつ、合計 2 回ストアに書き込みます。つまり、新規ユーザーの場合、Authentication エミュレータでは beforeSignIn から getAuth().getUser() を正常に呼び出すことができますが、本番環境ではエラーが発生します。

次のステップ