これは、Firebase Advent Calendar 2020 の2日目の記事です。
これは何?
Firebaseを利用してアプリやバックエンド開発を行う著者が、利用当初わかりにくかったことを整理しました😌
-
Firebase
には、Clientからの接続と管理者として接続する方法がありますが、この違いを整理します。- これにより、
Firebase
を商用利用する際の留意点や、鍵の管理について理解できます。
- これにより、
-
Firebase
にローカルで接続する方法を扱います。- これにより、たとえば
Cloud Functions
をローカルEmulatorで起動する際に、開発用のFirebaseに接続できるようになります。
- これにより、たとえば
Firebaseの利用方法の違い
Firebaseの接続に利用する鍵は下記の2種類があります。これらの違いが分かりにくかったので整理します。
- API Key (APIキー)
- Private key (秘密鍵)
違いについて、先にまとめます。
鍵の種別 | 利用用途 | 備考 |
---|---|---|
API Key | 外部に公開しユーザーが利用するようなClientとしての利用を想定。Webサービス、アプリなど | API Key自体は公開してもよいが、適切にセキュリティルールを設定することで、ユーザーごとにRead/Writeの権限を設定する。 Firebase SDK を利用。 |
Private Key | バックエンドの処理など、外部ユーザーは利用しない内部処理 | Private Key はセキュリティルールにかかわらずアクセスできてしまうため扱いに注意する(公開しないこと)。 Firebase Admin SDKを利用。 |
API Key - Clientとして利用する場合に利用する
API Key の利用については、ドキュメント: Firebase を 使ってみる > Web などに、利用用途の記述があります。
Firebase JavaScript SDK をウェブアプリで使用する手順について説明します。また、Node.js デスクトップや IoT アプリケーションなどのエンドユーザー アクセスのクライアントとして使用する場合も、この手順に従ってください。
つまり、簡単にいうと、外部に公開しユーザーが利用するようなClientとしての利用を想定している場合は、API Keyを利用するようにします。
上記ドキュメント通りに、API Keyを発行したら、 Firebase Configオブジェクト のとおり、API Keyを設定します。これは 公開前提 の値となります。
var firebaseConfig = {
apiKey: "API_KEY",
...
};
え、公開してしまって良いの?だれでもデータにアクセスできそうだけど大丈夫?!😱 と不安になりますが、大丈夫です。下記ドキュメントを読むとよくわかりますが、 セキュリティルール を必ず設定して、ユーザーごとに権限を適切に設定することが大切となります。
公式ドキュメント:FirebaseのAPIキーの使用と管理について学ぶより引用:
Unlike how API keys are typically used, API keys for Firebase services are not used to control access to backend resources; that can only be done with Firebase Security Rules.
つまり、下記のように明記されています。
FirebaseのAPIキーは、一般的なAPIキーとは異なる。FirebaseサービスのAPIキーはバックエンドリソースへのアクセスを制御するためには使用されず(=一般公開してもよいもので)、Firebaseのセキュリティルールでのみ可能
この辺りの話題は、先日のFirebase Summit2020でも Serverless security modeling in Firebase のトークで 06:39 API key management
あたりで述べられており、参考になります。
セキュリティルールについて簡単に触れると、
安全でないルールを修正する にあるように、読み込みできるデータ、書き込みできるデータなどの条件を設定することでセキュリティが担保できる仕組みです。
// わかりやすく例をすこし変えてみましたが、
// ユーザーデータは自分のデータしか読み書きできないような制約を設定します
service cloud.firestore {
match /databases/{database}/documents {
// Allow only authenticated content owners access
match /users/{userId} {
allow read, write: if request.auth.uid == request.resource.data.author_uid
}
}
}
Private Key - サーバーサイドで利用する
これまで説明したClient側の利用と反して、サーバーサイドの処理では セキュリティールール無視 でアクセス可能となります。1
そのため、サーバーサイドで利用するPrivate Key は扱いに注意が必要です。たとえば、Githubなどに誤ってコミットして一般公開してしまうなどしないようにしてください。
サーバーサイドの処理では、 Firebase Admin SDK を利用し、言語ごとの実装はドキュメントサーバーに Firebase Admin SDK を追加する に記載があります。
Firebaseへの接続
ローカルのAdmin SDKからFirebaseへ直接接続する
たとえばCloud FunctionsをローカルEmulatorで起動する際に、開発用のFirebaseに接続できるようにしたい、というニーズはよくあると思います。
下記の2種類の方法があります。
-
- 環境変数 GOOGLE_APPLICATION_CREDENTIALS の設定
-
- 環境変数 FIREBASE_CONFIG の設定
環境変数 GOOGLE_APPLICATION_CREDENTIALS に、PrivateKey(JSONファイル)のパスを指定する方法です。先ほどの、 Cloud FunctionsをローカルEmulatorで起動する際に、開発用のFirebaseに接続できるようにしたい
ニーズに利用するのはこちらの方法を使うのが楽でしょう。
環境変数 FIREBASE_CONFIG に、PrivateKeyのJSONをそのままいれるを入れる方法もあります。たとえば、CI環境でAdmin SDKを利用するような場合に有用そうです。これらの環境変数に関するドキュメントは、 こちらです です。
ローカルでFirebase Emulatorへ接続する
さきほどは、ローカルから直接Firebaseへ接続する方法を紹介しました。下記のような場合には、Firebaseに接続するのではなく、ローカルで起動したFirebase Emulatorへ接続する方法もあります。
- テストデータのみの環境で動作させたい
- たくさんのデータの更新を行うため、チームで共有しているFirebaseのデータを更新したくない
Firebase Emulatorへの接続は、Firebase SDK
では、 db.useEmulator("localhost", 8080);
のようにします。
Firebase Admin SDK
では、下記の環境変数を設定します。
export FIRESTORE_EMULATOR_HOST="localhost:8080" //Firestore
export FIREBASE_AUTH_EMULATOR_HOST="localhost:9099" //AUTH
さいごに
Cloud Firestore を利用されている方は、運用ツール fsrpl
が便利ですので、利用してみてください
また、技術書典10にて、Firestore*Testについての書籍を執筆中です。お楽しみに!
こちらに書籍が掲載されます👉https://techbookfest.org/organization/5712574639243264/
-
この仕様について、公式ドキュメントでの記載を確認できませんでしたが、FirebaseやFlutterに関する多くの技術発信をされているmonoさんのブログ にも記載があります。
セキュリティルールはあくまでクライアントからのアクセスルールを定義するものであって、Admin SDKからの操作には何の影響も及ぼしません。
↩