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、Firebase Authentication with 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 の料金プランをアップグレードする
Cloud Storage for Firebase を使用するには、Firebase プロジェクトが従量課金制(Blaze)のお支払いプラン(Cloud 請求先アカウントにリンクされている)である必要があります。
- Cloud 請求先アカウントには、クレジット カードなどのお支払い方法が必要です。
- Firebase と Google Cloud を初めて使用する場合は、$300 のクレジットと無料トライアル用 Cloud 請求先アカウントを利用できるかどうか確認してください。
- この Codelab をイベントの一環として実施する場合は、利用可能な Cloud クレジットがあるかどうかを主催者に確認してください。
プロジェクトを Blaze プランにアップグレードする手順は次のとおりです。
- Firebase コンソールで、プランをアップグレードを選択します。
- Blaze プランを選択します。画面上の手順に沿って、Cloud 請求先アカウントをプロジェクトにリンクします。
このアップグレードの一環として Cloud 請求先アカウントを作成する必要があった場合は、Firebase コンソールのアップグレード フローに移動してアップグレードを完了する必要があります。
Firebase ウェブアプリをプロジェクトに追加する
- ウェブアイコン をクリックして、新しい Firebase ウェブアプリを作成します。
- ニックネーム「Friendly Chat」でアプリを登録し、[このアプリの Firebase Hosting も設定します] の横のチェックボックスをオンにします。[アプリを登録] をクリックします。
- 次のステップでは、npm と構成オブジェクトを使用して Firebase をインストールするコマンドが表示されます。このオブジェクトは Codelab の後半でコピーするので、今は [次へ] をクリックします。
- Firebase CLI をインストールするオプションが表示されます。まだインストールしていない場合は、
npm install -g firebase-tools
コマンドを使用してインストールします。[Next] をクリックします。 - Firebase にログインして Firebase Hosting にデプロイするオプションが表示されます。コマンド
firebase login
を使用して Firebase にログインし、[コンソールに進む] をクリックします。Firebase Hosting へのデプロイは後で行う予定です。
Firebase Authentication 用に Google ログインを有効にする
ユーザーが Google アカウントでウェブアプリにログインできるように、Google ログイン方法を使用します。
Google ログインを有効にする必要があります。
- Firebase コンソールの左側のパネルで、[Build] セクションを見つけます。
- [Authentication] をクリックし、必要に応じて [Get Started] をクリックして、[Sign-in method] タブをクリックします(または、ここをクリックして直接移動します)。
- Google ログイン プロバイダを有効にする
- アプリの公開名を「Friendly Chat」に設定し、プルダウン メニューからプロジェクト サポートのメールアドレスを選択します。
- [保存] をクリックします。
Cloud Firestore を設定する
このウェブアプリは Cloud Firestore を使用してチャット メッセージを保存し、新しいチャット メッセージを受信します。
Firebase プロジェクトで Cloud Firestore を設定する方法は次のとおりです。
- Firebase コンソールの左側のパネルで [Build] を開き、[Firestore データベース] を選択します。
- [データベースを作成] をクリックします。
- [データベース ID] は
(default)
のままにします。 - データベースのロケーションを選択し、[次へ] をクリックします。
実際のアプリの場合は、ユーザーに近いロケーションを選択します。 - [テストモードで開始] をクリックします。セキュリティ ルールに関する免責条項を確認します。
この Codelab の後半で、セキュリティ ルールを追加してデータを保護します。データベースのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。 - [作成] をクリックします。
Cloud Storage for Firebase を設定する
このウェブアプリは Cloud Storage for Firebase を使用して画像ファイルを保存、アップロード、共有します。
Firebase プロジェクトで Cloud Storage for Firebase を設定する方法は次のとおりです。
- Firebase コンソールの左側のパネルで [Build] を開き、[Storage] を選択します。
- [開始] をクリックします。
- デフォルトの Storage バケットのロケーションを選択します。
US-WEST1
、US-CENTRAL1
、US-EAST1
のバケットでは、Google Cloud Storage の「Always Free」階層を利用できます。他のすべてのロケーションのバケットは、Google Cloud Storage の料金と使用量に従います。 - [テストモードで開始] をクリックします。セキュリティ ルールに関する免責条項を確認します。
この Codelab の後半で、セキュリティ ルールを追加してデータを保護します。Storage バケットのセキュリティ ルールを追加せずに、アプリを配布または公開しないでください。 - [作成] をクリックします。
4. Firebase を構成する
appcheck-start
ディレクトリから、以下を呼び出します。
firebase use --add
プロンプトが表示されたら、プロジェクト ID を選択して、Firebase プロジェクトにエイリアスを指定します。このプロジェクトでは、エイリアスを default に設定します。次に、Firebase で動作するようにローカル プロジェクトを構成する必要があります。
- Firebase コンソールのプロジェクト設定に移動します。
- [マイアプリ] カードで、構成オブジェクトが必要なアプリのニックネームを選択します。
- Firebase SDK スニペット ペインで [Config] を選択します。
- 構成オブジェクトのスニペットをコピーして
appcheck-start/hosting/src/firebase-config.js
に追加します。コードラボの残りの部分では、変数の名前が 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
を実行して、ウェブ アプリケーションをウェブにデプロイします。この部分は、reCAPTCHA Enterprise 構成証明プロバイダ用にドメインを構成する必要があるため、App Check が実際にどのように機能するかをデモするうえで重要なステップです。
アプリが提供するデフォルトの機能が動作していると思います。チャット メッセージの投稿など、このアプリからのみ行う必要がある操作。現在の状態の欠点は、前の手順で作成したアプリ構成を知っている人なら誰でもバックエンド リソースにアクセスできることです。これらのサービスは、Firestore システムと Cloud Storage システムで設定されているセキュリティ ルールに従う必要がありますが、それ以外は、そこに保存されているデータに対してクエリを実行したり、保存したり、アクセスしたりできます。
次の手順では、次の操作を行います。
- App Check に登録する
- 適用を検証する
- ルールの適用を開始する
6. App Check と適用を有効にする
まず、プロジェクト用の reCAPTCHA Enterprise キーを取得して App Check に追加します。まず、Google Cloud コンソールの [reCAPTCHA Enterprise] セクションに移動します。プロジェクトを選択すると、reCAPTCHA Enterprise API を有効にするよう求めるメッセージが表示されます。API を有効にして、完了するまで数分待ちます。[エンタープライズ鍵] の横にある [鍵を作成] をクリックします。このセクションで、表示名を指定し、[ウェブサイト] タイプのキーを選択します。アプリをホストするドメインを指定する必要があります。Firebase Hosting でホストする予定であるため、デフォルトのホスト名(通常は ${YOUR_PROJECT_ID}.web.app
)を使用します。ホスティング ドメインは、Firebase コンソールの [Hosting] セクションで確認できます。情報を入力したら、[完了]、[鍵を作成] の順にクリックします。
完了すると、[キーの詳細] ページの上部に 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 の適用をオフにできます。次のセクションでは、Friendly Chat の例に 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 ドメインのみを reCAPTCHA 構成証明プロバイダに登録し、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 の設定] に入力します。
トークンに覚えやすい一意の名前を付け、[保存] をクリックします。このオプションを使用すると、アプリでクライアント生成トークンを使用できます。これは、デバッグ トークンを生成してアプリに埋め込むよりも安全な方法です。アプリ内にトークンを埋め込むと、トークンがエンドユーザーに誤って配布され、エンドユーザーがチェックをバイパスしてトークンを悪用する可能性があります。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 を以下に追加する方法については、次のドキュメントをご覧ください。