1. はじめに
最終更新日: 2023 年 2 月 23 日
Firebase リソースへの不正アクセスを防ぐにはどうすればよいですか。
Firebase App Check を使用すると、受信リクエストに正規のアプリから送信されたことを示す証明書の添付を必須にし、適切な証明書がないトラフィックをブロックすることで、未承認のクライアントがバックエンド リソースにアクセスすることを防止できます。Firebase App Check は、プラットフォーム固有の証明書プロバイダを使用してクライアントの真正性を検証します。ウェブアプリの場合、証明書プロバイダとして reCAPTCHA v3 と reCAPTCHA Enterprise を使用できます。
App Check は、Cloud Firestore、Realtime Database、Cloud Functions、Firebase Authentication と Identity Platform へのリクエストや、自社でホストするバックエンドへのリクエストの保護に使用できます。
作成するアプリの概要
この 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 プロジェクトを作成する
- Firebase にログインします。
- Firebase コンソールで [プロジェクトを追加] をクリックし、Firebase プロジェクトに FriendlyChat という名前を付けます。Firebase プロジェクトのプロジェクト ID を覚えておいてください。
- [このプロジェクトで Google アナリティクスを有効にする] チェックボックスをオフにします
- [プロジェクトを作成] をクリックします。
これから作成するアプリケーションは、ウェブアプリで利用可能な Firebase プロダクトを使用します。
- ユーザーがアプリに簡単にログインできるようにする Firebase Authentication。
- Cloud Firestore を使用すると、構造化データをクラウドに保存し、データが変更されたときにすぐに通知を受け取ることができます。
- Cloud Storage for Firebase を使用してクラウドにファイルを保存します。
- Firebase Hosting を使用してアセットをホストし、提供します。
- プッシュ通知を送信し、ブラウザのポップアップ通知を表示する Firebase Cloud Messaging。
- Firebase Performance Monitoring は、アプリのユーザー パフォーマンス データを収集します。
これらのプロダクトの一部は、特別な構成が必要な場合や、Firebase コンソールを使用して有効にする必要があります。
プロジェクトに Firebase ウェブアプリを追加する
- ウェブアイコン をクリックして、新しい Firebase ウェブアプリを作成します。
- 「Friendly Chat」というニックネームでアプリを登録し、[このアプリの Firebase Hosting も設定します] の横にあるチェックボックスをオンにし、[アプリを登録] をクリックします。
- 次のステップでは、npm と構成オブジェクトを使用して Firebase をインストールするコマンドが表示されます。このオブジェクトは Codelab の後半でコピーするので、ここでは [Next] を押します。
- Firebase CLI をインストールするオプションが表示されます。まだインストールしていない場合は、ここで
npm install -g firebase-tools
コマンドを使用してインストールします。[次へ] をクリックします。 - Firebase にログインして Firebase Hosting にデプロイするオプションが表示されます。
firebase login
コマンドを使用して Firebase にログインし、[コンソールに進む] をクリックします。Firebase Hosting へのデプロイは後のステップで行います。
Firebase Authentication に対して Google ログインを有効にする
ユーザーが Google アカウントでウェブアプリにログインできるようにするために、Google ログイン方法が使用されます。
Google ログインを有効にする必要があります。
- Firebase コンソールで、左側のパネルにある [ビルド] セクションを見つけます。
- [Authentication] をクリックし、該当する場合は [Get Started] をクリックしてから、[Sign-in method] タブをクリックします(または、こちらをクリックして直接移動します)。
- Google ログイン プロバイダを有効にする
- アプリの公開名を [Friendly Chat] に設定し、プルダウン メニューからプロジェクト サポートメールを選択します。
- [保存] をクリックします。
Cloud Firestore の有効化
このウェブアプリは、Cloud Firestore を使用してチャット メッセージを保存し、新しいチャット メッセージを受信します。
Cloud Firestore を有効にする必要があります。
- Firebase コンソールの [構築] セクションで、[Firestore データベース] をクリックします
- Cloud Firestore ペインで [データベースを作成] をクリックします。
- [テストモードで開始] オプションを選択し、セキュリティ ルールに関する免責条項を読み、[次へ] をクリックします。
テストモードを使用すると、開発中にデータベースに自由に書き込むことができます。スターター コードには、すでにセキュリティ ルールが記述されています。この Codelab ではこれらを使用します。
- Cloud Firestore データを保存するロケーションを設定します。デフォルトのままにするか、近くのリージョンを選択します。[有効にする] をクリックして Firestore をプロビジョニングします。
Cloud Storage を有効にする
このウェブアプリは、Cloud Storage for Firebase を使用して画像を保存、アップロード、共有します。
Cloud Storage を有効にする必要があります。
- Firebase コンソールの [ビルド] セクションで、[Storage] をクリックします。
- [使ってみる] ボタンが表示されていない場合は、Cloud Storage はすでに有効になっているため、以下の手順を行う必要はありません。
- [利用開始] をクリックします。
- [テストモードで開始] オプションを選択し、セキュリティ ルールに関する免責条項を読み、[次へ] をクリックします。
デフォルトのセキュリティ ルールでは、認証されたユーザーであれば誰でも Cloud Storage に何でも書き込めます。この Codelab の後半で、作成済みのセキュリティ ルールをデプロイします。
- Cloud Storage のロケーションは、Cloud Firestore データベース用に選択したのと同じリージョンで事前に選択されています。[完了] をクリックして設定を完了します。
4. Firebase を構成する
appcheck-start
ディレクトリから、次のコマンドを実行します。
firebase use --add
プロンプトが表示されたら、プロジェクト ID を選択し、Firebase プロジェクトにエイリアスを指定します。このプロジェクトでは、エイリアスに default を割り当てます。次に、Firebase と連携するようにローカル プロジェクトを構成する必要があります。
- Firebase コンソールの [プロジェクトの設定] に移動します。
- [アプリ] カードで、構成オブジェクトが必要なアプリのニックネームを選択します。
- Firebase SDK スニペット ペインで [Config] を選択します。
- 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.appspot.com",
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
を実行して、ウェブ アプリケーションをウェブにデプロイします。このパートは、reCAPTCHA Enterprise 証明書プロバイダ用にドメインを構成する必要があるため、実際の環境で App Check がどのように機能するかのデモを行ううえで重要なステップです。
アプリが提供するデフォルトの機能を体験してみてください。チャット メッセージなど、このようなアプリでのみ行うべきことはすべて投稿します。現在の状態のデメリットは、前のステップで作成したアプリ構成を持つすべてのユーザーがバックエンド リソースにアクセスできることです。Firestore と Cloud Storage のシステムに適用されるセキュリティ ルールに引き続き従う必要がありますが、そうしないと、そこに保存されているデータのクエリ、保存、アクセスを行うことができます。
次のステップでは、次のことを行います。
- App Check に登録する
- 適用を検証する
- ルールの適用を開始する
6. App Check と適用を有効にする
まず、プロジェクトの reCAPTCHA Enterprise キーを取得して App Check に追加します。まず、Google Cloud コンソールの [reCAPTCHA Enterprise] セクションにアクセスします。プロジェクトを選択すると、reCAPTCHA Enterprise API を有効にするように求められます。API を有効にして、終了するまで数分待ちます。次に、[Enterprise keys] の横にある [Create Key] をクリックします。このセクションでは、表示名を指定し、ウェブサイト タイプのキーを選択します。アプリがホストされているドメインを指定する必要があります。これを Firebase Hosting でホストする予定なので、デフォルトのホスティング名(通常は ${YOUR_PROJECT_ID}.web.app
)を使用します。ホスティング ドメインは、Firebase コンソールの [Hosting] セクションで確認できます。これらの情報を入力したら、[完了]、[キーを作成] の順に押します。
完了すると、[Key Details] ページの上部に ID が表示されます。
この ID をクリップボードにコピーします。これは App Check に使用する鍵です。次に、Firebase コンソールの [App Check] セクションにアクセスし、[開始] をクリックします。[登録] をクリックし、[reCAPTCHA Enterprise] をクリックして、コピーした ID を [reCAPTCHA Enterprise のサイトキー] のテキスト ボックスに入力します。その他の設定はデフォルトのままにします。[App Check] ページは次のようになります。
未検証のリクエストと未適用のリクエスト
これで、Firebase コンソールにキーが登録されたので、firebase serve
を実行して、ブラウザでのサイトの実行に戻ります。これで、ウェブアプリがローカルで実行され、Firebase バックエンドに対するリクエストを再開できるようになりました。リクエストは Firebase バックエンドに送信されるため、これらのリクエストは App Check によってモニタリングされますが、適用されません。送信されたリクエストのステータスを確認するには、Firebase コンソールで [App Check] ページの [API] タブにある Cloud Firestore セクションを確認します。App Check を使用するようにクライアントをまだ構成していないため、次のように表示されます。
バックエンドで未検証のリクエストがすべて受信されています。この画面は、ほぼすべてのクライアント リクエストが 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.
Firebase リソースへのリクエストで有効な証明書トークンを渡さなかったリクエストをブロックする App Check です。当面は App Check の適用をオフにできます。次のセクションでは、フレンドリー チャットの例に reCAPTCHA Enterprise App Check を追加する方法について説明します。
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
を実行します。アプリケーションがまだローカルに読み込まれていないことがわかります。これは、Firebase ドメインを localhost ドメインではなく reCAPTCHA 証明書プロバイダにのみ登録しているためです。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 configuration] に挿入します。
トークンに覚えやすい一意の名前を付けて、[保存] をクリックします。このオプションを使用すると、クライアントが生成したトークンをアプリで使用できます。これは、デバッグ トークンを生成してアプリケーションに埋め込むよりも安全な代替手段です。トークンをアプリに埋め込むと、誤ってエンドユーザーにトークンが配布され、エンドユーザーがチェックをすり抜けて悪用される可能性があります。たとえば 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 がウェブアプリに正常に追加されました。
本番環境の reCAPTCHA Enterprise トークンを処理するように Firebase コンソールを設定し、ローカル開発用のデバッグ トークンも設定します。これにより、承認されたクライアントから Firebase リソースに引き続きアクセスでき、アプリケーション内からの不正行為を防ぐことができます。
次のステップ
Firebase App Check を追加するには、次のドキュメントをご覧ください。