App Check ウェブ Codelab

1. はじめに

最終更新日: 2023 年 2 月 23 日

Firebase リソースへの不正アクセスを防ぐにはどうすればよいですか?

Firebase App Check を使用すると、受信リクエストに正規のアプリからのリクエストであることを示す証明書を添付することを要求し、適切な証明書がないトラフィックをブロックすることで、未承認のクライアントがバックエンド リソースにアクセスするのを防ぐことができます。Firebase App Check は、プラットフォーム固有の証明書プロバイダを利用してクライアントの真正性を検証します。ウェブアプリの場合、App Check は証明書プロバイダとして reCAPTCHA v3 と reCAPTCHA Enterprise をサポートしています。

App Check を使用すると、Cloud Firestore、Realtime Database、Cloud Functions、Identity Platform を使用する Firebase Authentication、および独自にホストするバックエンドへのリクエストを保護できます。

作成するアプリの概要

この Codelab では、App Check を追加して適用することで、チャット アプリケーションを保護します。

作成した最初のフレンドリーなチャットアプリ。

学習内容

  • バックエンドで不正アクセスをモニタリングする方法
  • Firestore と Cloud Storage に適用を追加する方法
  • ローカル開発用のデバッグ トークンを使用してアプリケーションを実行する方法

必要なもの

  • 任意の IDE / テキスト エディタ
  • パッケージ マネージャー npm(通常は Node.js に付属)
  • Firebase CLI がインストールされ、アカウントで動作するように構成されている
  • ターミナル / コンソール
  • 任意のブラウザ(Chrome など)
  • Codelab のサンプルコード(コードの取得方法については、Codelab の次のステップをご覧ください)

2. サンプルコードを取得する

コマンドラインから、Codelab の GitHub リポジトリのクローンを作成します。

git clone https://github.com/firebase/codelab-friendlychat-web

または、Git がインストールされていない場合は、リポジトリを ZIP ファイルとしてダウンロードすることもできます。

スターター アプリをインポートする

IDE を使用して、クローンを作成したリポジトリから 📁 appcheck-start ディレクトリを開くか、インポートします。この 📁 appcheck-start ディレクトリには、Codelab の開始コードが含まれています。これは、完全に機能するチャット ウェブアプリです。📁 appcheck ディレクトリには、Codelab の完成したコードが含まれています。

3. Firebase プロジェクトを作成して設定する

Firebase プロジェクトを作成する

  1. Google アカウントを使用して Firebase コンソールにログインします。
  2. ボタンをクリックして新しいプロジェクトを作成し、プロジェクト名(例: FriendlyChat)を入力します。
  3. [続行] をクリックします。
  4. Firebase の利用規約が表示されたら、内容を読み、同意して [続行] をクリックします。
  5. (省略可)Firebase コンソールで AI アシスタンス(「Gemini in Firebase」)を有効にします。
  6. この Codelab では Google アナリティクスは不要なため、Google アナリティクスのオプションをオフにします。
  7. [プロジェクトを作成] をクリックし、プロジェクトがプロビジョニングされるまで待ってから、[続行] をクリックします。

Firebase の料金プランをアップグレードする

Cloud Storage for Firebase を使用するには、Firebase プロジェクトが従量課金制(Blaze)の料金プランに登録されている必要があります。つまり、Cloud 請求先アカウントにリンクされている必要があります。

  • Cloud 請求先アカウントには、クレジット カードなどのお支払い方法を設定する必要があります。
  • Firebase と Google Cloud を初めて使用する場合は、$300 のクレジットと無料トライアル用 Cloud 請求先アカウントを利用できるかどうかご確認ください。
  • イベントの一環としてこの Codelab を行う場合は、利用可能な Cloud クレジットがあるかどうかを主催者に確認してください。

プロジェクトを Blaze プランにアップグレードする手順は次のとおりです。

  1. Firebase コンソールで、プランをアップグレードします。
  2. Blaze プランを選択します。画面上の手順に沿って、Cloud 請求先アカウントをプロジェクトにリンクします。
    このアップグレードの一環として Cloud 請求先アカウントを作成する必要があった場合は、Firebase コンソールのアップグレード フローに戻ってアップグレードを完了する必要があります。

プロジェクトに Firebase ウェブアプリを追加する

  1. ウェブアイコン 58d6543a156e56f9.png をクリックして、新しい Firebase ウェブアプリを作成します。
  2. ニックネーム「Friendly Chat」でアプリを登録し、[このアプリの Firebase Hosting も設定します] の横にあるチェックボックスをオンにします。[アプリを登録] をクリックします。
  3. 次のステップでは、npm と構成オブジェクトを使用して Firebase をインストールするコマンドが表示されます。このオブジェクトは、この Codelab で後ほどコピーします。ここでは [次へ] をクリックします。

[ウェブアプリに Firebase を追加] ウィンドウ

  1. Firebase CLI をインストールするオプションが表示されます。まだインストールしていない場合は、npm install -g firebase-tools コマンドを使用してインストールします。[次へ] をクリックします。
  2. 次に、Firebase にログインして Firebase Hosting にデプロイするオプションが表示されます。firebase login コマンドを使用して Firebase にログインし、[コンソールに進む] をクリックします。Firebase Hosting へのデプロイは後のステップで行います。

Firebase プロダクトを設定する

これから構築するアプリケーションでは、ウェブアプリに使用できる Firebase プロダクトを使用します。

  • ユーザーがアプリに簡単にログインできるようにするための Firebase Authentication。
  • Cloud Firestore: 構造化データをクラウドに保存し、データが変更されたときに即座に通知を受け取ります。
  • Cloud Storage for Firebase。ファイルをクラウドに保存します。
  • アセットをホストして提供するための Firebase Hosting。
  • Firebase Cloud Messaging: プッシュ通知を送信し、ブラウザのポップアップ通知を表示します。
  • Firebase Performance Monitoring。アプリのユーザー パフォーマンス データを収集します。

この中には、特別な設定が必要になるプロダクトや、Firebase コンソールを使用して有効化する必要があるプロダクトがあります。

Firebase Authentication で Google ログインを有効にする

ユーザーが Google アカウントを使用してウェブアプリにログインできるようにするには、Google ログイン方法を使用します。

Google ログインを有効にする必要があります。

  1. Firebase コンソールの左側のパネルで [構築] セクションを見つけます。
  2. [Authentication] をクリックし、該当する場合は [始める] をクリックしてから、[ログイン方法] タブをクリックします(または、ここをクリックして直接移動します)。
  3. Google ログイン プロバイダを有効にする
  4. アプリの公開名を「Friendly Chat」に設定し、プルダウン メニューからプロジェクトのサポートメールを選択します。
  5. [保存] をクリックします。

f96888973c3d00cc.png

Cloud Firestore を設定する

このウェブアプリは Cloud Firestore を使用してチャット メッセージを保存し、新しいチャット メッセージを受信します。

Firebase プロジェクトで Cloud Firestore を設定する方法は次のとおりです。

  1. Firebase コンソールの左側のパネルで [ビルド] を展開し、[Firestore データベース] を選択します。
  2. [データベースを作成] をクリックします。
  3. [データベース ID] は (default) のままにします。
  4. データベースのロケーションを選択し、[次へ] をクリックします。
    実際のアプリでは、ユーザーに近いロケーションを選択します。
  5. [テストモードで開始する] をクリックします。セキュリティ ルールに関する免責条項を確認します。
    この Codelab の後半で、データを保護するためのセキュリティ ルールを追加します。データベースのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。
  6. [作成] をクリックします。

Cloud Storage for Firebase を設定する

このウェブアプリは Cloud Storage for Firebase を使用して、画像の保存、アップロード、共有を行います。

Firebase プロジェクトで Cloud Storage for Firebase を設定する方法は次のとおりです。

  1. Firebase コンソールの左側のパネルで [ビルド] を展開し、[Storage] を選択します。
  2. [開始] をクリックします。
  3. デフォルトの Storage バケットのロケーションを選択します。
    US-WEST1、US-CENTRAL1、US-EAST1 のバケットは、Google Cloud Storage の「Always Free」枠を利用できます。他のすべてのロケーションのバケットは、Google Cloud Storage の料金と使用量に従います。
  4. [テストモードで開始する] をクリックします。セキュリティ ルールに関する免責条項を確認します。
    この Codelab の後半で、データを保護するためのセキュリティ ルールを追加します。Storage バケットのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。
  5. [作成] をクリックします。

4. Firebase を構成する

appcheck-start ディレクトリから、次のコマンドを実行します。

firebase use --add

プロンプトが表示されたら、プロジェクト ID を選択し、Firebase プロジェクトにエイリアスを付けます。このプロジェクトでは、default というエイリアスを指定します。次に、Firebase と連携するようにローカル プロジェクトを構成する必要があります。

  1. Firebase コンソールの [プロジェクトの設定] に移動します。
  2. [マイアプリ] カードで、構成オブジェクトが必要なアプリのニックネームを選択します。
  3. Firebase SDK スニペット ペインで [構成] を選択します。
  4. config オブジェクトのスニペットをコピーして、appcheck-start/hosting/src/firebase-config.js に追加します。この Codelab の残りの部分では、変数の名前が config であると仮定します。

firebase-config.js

const config = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://PROJECT_ID.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.firebasestorage.app",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

同じ appcheck-start ディレクトリから、次のコマンドを呼び出します。

firebase experiments:enable webframeworks

これにより、このプロジェクトのビルドに使用されたウェブ フレームワークのサポートが有効になります。

これで、プロジェクトを実行して、デフォルトのプロジェクトが機能することをテストする準備が整いました。

5. App Check を使用せずにアプリを試す

アプリを構成し、SDK をセットアップしたら、本来の設計どおりにアプリを使用してみます。まず、すべての依存関係をインストールします。ターミナルから appcheck-start/hosting ディレクトリに移動します。そのディレクトリ内で npm install を実行します。これにより、プロジェクトが機能するために必要なすべての依存関係が取得されます。現在の状態でアプリを起動するには、firebase serve を実行します。アプリから Google アカウントでのログインを求められます。ログインしたら、チャット メッセージと写真をいくつかチャットに投稿してみます。

ローカルでテストしたので、次は本番環境で確認してみましょう。firebase deploy を実行して、ウェブ アプリケーションをウェブにデプロイします。この部分は、App Check が実際の環境でどのように機能するかをデモするうえで重要なステップです。reCAPTCHA Enterprise 認証プロバイダにドメインを構成する必要があるためです。

アプリが提供するデフォルトの機能が利用できるようになっているはずです。チャット メッセージの投稿など、このようなアプリからのみ行うべき操作。現在の状態のデメリットは、前のステップのアプリ構成を知っているユーザーであれば誰でもバックエンド リソースにアクセスできることです。Firestore と Cloud Storage のシステムに適用されているセキュリティ ルールに従う必要がありますが、それ以外の場合は、そこに保存されているデータのクエリ、保存、アクセスを行うことができます。

次のいくつかのステップでは、次の操作を行います。

  • App Check に登録する
  • 違反措置を検証する
  • ルールの適用を開始する

6. App Check と適用を有効にする

まず、プロジェクトの reCAPTCHA Enterprise キーを取得して App Check に追加します。まず、Google Cloud コンソールの [reCAPTCHA Enterprise] セクションにアクセスします。プロジェクトを選択すると、reCAPTCHA Enterprise API を有効にするよう求めるメッセージが表示されます。API を有効にして、完了するまで数分待ちます。[Enterprise キー] の横にある [キーを作成] をクリックします。このセクションで表示名を指定し、[ウェブサイト] タイプのキーを選択します。アプリをホストするドメインを指定する必要があります。このアプリを Firebase Hosting でホストする予定なので、デフォルトのホスティング名(通常は ${YOUR_PROJECT_ID}.web.app)を使用します。ホスティング ドメインは、Firebase コンソールの Hosting セクションで確認できます。この情報を入力したら、[完了]、[鍵を作成] の順にクリックします。

reCAPTCHA のキー作成画面

完了すると、[鍵の詳細] ページの上部に ID が表示されます。

reCAPTCHA Enterprise の登録ウィンドウ

この ID をクリップボードにコピーします。これは、App Check に使用するキーです。次に、Firebase コンソールの [App Check] セクションに移動し、[使ってみる] をクリックします。次に、[Register] をクリックし、[reCAPTCHA Enterprise] をクリックして、コピーした ID を [reCAPTCHA Enterprise Site Key] のテキスト ボックスに貼り付けます。その他の設定はデフォルトのままにします。[App Check] ページは次のようになります。

reCAPTCHA Enterprise トークンを登録する App Check アプリ ウィンドウ

未確認のリクエストと未適用のリクエスト

Firebase コンソールにキーを登録したので、firebase serve を実行して、ブラウザでサイトを再度実行します。これで、ウェブアプリがローカルで実行され、Firebase バックエンドに対してリクエストを再度送信できるようになりました。リクエストが Firebase バックエンドに対して行われると、これらのリクエストは App Check によってモニタリングされますが、適用はされません。受信したリクエストのステータスを確認するには、Firebase コンソールの [App Check] ページの [API] タブにある [Cloud Firestore] セクションにアクセスします。クライアントが App Check を使用するようにまだ構成していないため、次のようなメッセージが表示されます。

アプリに対する未検証のクライアント リクエストが 100% であることを示す App Check ダッシュボード。

バックエンドには、100% 未検証のリクエストが届いています。この画面は、ほぼすべてのクライアント リクエストが App Check を統合していないクライアントから送信されていることを示しているため、便利です。

このダッシュボードから、いくつかのことがわかります。まず、すべてのクライアント アプリで最新バージョンのクライアントが実行されているかどうかを確認できます。そうであれば、アプリケーションの正規のクライアントのアクセスをオフにすることを心配せずに、App Check を安全に適用できます。この指標から、アプリ内からではなく、バックエンドにアクセスしようとした試行回数もわかります。これは、ユーザーがバックエンドに直接クエリを実行している可能性があります。リクエストが検証されていないことがわかったので、リクエストを検証する前に、バックエンドへのリクエストが検証されていないユーザーに何が起こるかを確認しましょう。

未確認のリクエストと適用されたリクエスト

前の画面で [適用] ボタンを押し、プロンプトが表示されたらもう一度 [適用] を押します。

未確認の指標ダッシュボードで [適用] ボタンがハイライト表示されている

これにより、App Check の適用が開始されます。選択した証明書プロバイダ(この場合は reCAPTCHA Enterprise)で検証されていないバックエンド サービスへのリクエストがブロックされるようになります。http://localhost:5000 で実行されているウェブアプリに戻ります。ページを更新してデータベースからデータを取得しようとしても、何も起こりません。Chrome コンソールを開いてエラーを確認すると、次のようなエラーが表示されます。

Uncaught Error in snapshot listener: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

これは、App Check が、Firebase リソースへのリクエストで有効な証明書トークンを渡さなかったリクエストをブロックしていることを示しています。ここでは、App Check の適用をオフにして、次のセクションで、reCAPTCHA Enterprise App Check を Friendly Chat のサンプルに追加する方法を確認します。

7. reCAPTCHA Enterprise キーをサイトに追加する

アプリケーションにエンタープライズ キーを追加します。まず、hosting/src/firebase-config.js を開き、次のコード スニペットに reCAPTCHA Enterprise キーを追加します。

const reCAPTCHAEnterpriseKey = {
  // Replace with your recaptcha enterprise site key
  key: "Replace with your recaptcha enterprise site key"
};

この処理が完了したら、hosting/src/index.js を開き、51 行目に firebase-config.js からのインポートを追加して reCAPTCHA キーを取得します。また、App Check ライブラリをインポートして、reCAPTCHA Enterprise プロバイダを操作できるようにします。

// add from here
 import {
   initializeAppCheck,
   ReCaptchaEnterpriseProvider,
 } from 'firebase/app-check';
// to here

// replace this line
import { getFirebaseConfig } from './firebase-config.js';
// with this line
import { getFirebaseConfig, getReCaptchaKey } from './firebase-config.js';

次の行で、App Check を設定する関数を作成します。この関数は、まず開発環境にいるかどうかを確認し、開発環境にいる場合は、ローカル開発に使用できるデバッグ トークンを出力します。

import { getFirebaseConfig, getReCaptchaKey } from './firebase-config.js';
// add from here
 function setupAppCheck(app) {
   if(import.meta.env.MODE === 'development') {
     self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
   }
 }
// to here

次に、選択したプロバイダ(この場合は reCAPTCHA Enterprise)で動作するように App Check を初期化します。また、App Check トークンをバックグラウンドで自動的に更新することもできます。これにより、App Check トークンが古くなった場合に、ユーザーがサービスを操作する際の遅延を防ぐことができます。

function setupAppCheck(app) {
   if(import.meta.env.MODE === 'development') {
     self.FIREBASE_APPCHECK_DEBUG_TOKEN = true;
   }
// add from here
   // Create a ReCaptchaEnterpriseProvider instance using your reCAPTCHA Enterprise
   // site key and pass it to initializeAppCheck().
   initializeAppCheck(app, {
     provider: new ReCaptchaEnterpriseProvider(getReCaptchaKey()),
     isTokenAutoRefreshEnabled: true // Set to true to allow auto-refresh.
   });
// to here
 }

最後に、アプリが初期化されていることを確認したら、先ほど作成した setupAppCheck 関数を呼び出す必要があります。hosting/src/index.js ファイルの下部に、最近追加したメソッドの呼び出しを追加します。

const firebaseApp = initializeApp(getFirebaseConfig());
// add from here
setupAppCheck(firebaseApp);
// to here
getPerformance();
initFirebaseAuth();
loadMessages();

まずはローカルでテストする

まず、アプリケーションをローカルでテストします。アプリケーションをローカルでまだ提供していない場合は、firebase serve を実行します。アプリケーションがローカルで読み込まれないことがわかります。これは、reCAPTCHA 証明書プロバイダに Firebase ドメインのみを登録し、localhost ドメインを登録していないためです。localhost を承認済みドメインとして登録しないでください。ユーザーが自分のマシンでローカルに実行されているアプリケーションから、制限付きのバックエンドにアクセスできるようになります。代わりに、self.FIREBASE_APPCHECK_DEBUG_TOKEN = true を設定したため、JavaScript コンソールで次のような行を確認します。

App Check debug token: 55183c20-de61-4438-85e6-8065789265be. You will need to add it to your app's App Check settings in the Firebase console for it to work.

提供されたデバッグ トークン(この例では 55183c20-de61-4438-85e6-8065789265be)を取得し、アプリのオーバーフロー メニューにある [App Check の構成] にプラグインします。

[デバッグ トークンを管理] の場所を示す App Check ダッシュボード

トークンに一意の名前を付けて、[保存] をクリックします。このオプションを使用すると、クライアントが生成したトークンをアプリで使用できます。これは、デバッグ トークンを生成してアプリケーションに埋め込むよりも安全な方法です。アプリ内にトークンを埋め込むと、誤ってエンドユーザーに配布される可能性があり、エンドユーザーはチェックを回避してトークンを悪用する可能性があります。CI 環境などでデバッグ トークンを配布する場合は、こちらのドキュメントで配布方法の詳細をご覧ください。

エイリアスを使用してデバッグ トークンを入力する例

Firebase コンソールにデバッグ トークンを登録したら、App Check の適用を再度有効にし、ターミナルから firebase serve を呼び出して、アプリのコンテンツがローカルで読み込まれることをテストできます。以前に入力したデータが、ウェブ アプリケーションのローカル バージョンに提供されていることがわかります。デバッグ トークンを含むメッセージがコンソールに表示されます。

本番環境で試す

App Check がローカルで動作することを確認したら、ウェブ アプリケーションを本番環境にデプロイします。ターミナルから firebase deploy を再度呼び出し、ページを再読み込みします。これにより、ウェブ アプリケーションが Firebase Hosting で実行できるようにパッケージ化されます。アプリケーションが Firebase Hosting でホストされたら、${YOUR_PROJECT_ID}.web.app でアプリケーションにアクセスしてみてください。JavaScript コンソールを開くと、デバッグ トークンが表示されなくなり、プロジェクトにチャットが読み込まれるようになります。また、アプリケーションをしばらく操作した後、Firebase コンソールの [App Check] セクションにアクセスして、アプリケーションへのリクエストがすべて検証済みに切り替わっていることを確認できます。

8. 完了

これで、ウェブアプリに Firebase App Check を正常に追加できました。

Firebase コンソールを設定して、本番環境用の reCAPTCHA Enterprise トークンを処理し、ローカル開発用のデバッグ トークンも設定しました。これにより、アプリは承認済みのクライアントから Firebase リソースに引き続きアクセスできるようになり、アプリケーション内での不正行為の発生を防ぐことができます。

次のステップ

Firebase App Check を追加する方法については、次のドキュメントをご覧ください。

リファレンス ドキュメント