Firebase Realtime Database ルールでは、データベースへの読み取り / 書き込みアクセス権を持つユーザー、データが構造化される仕組み、存在するインデックスを決定します。これらのルールは Firebase サーバー上にあり、常時自動的に適用されます。読み取り / 書き込みリクエストはすべて、ルールで許可された場合にのみ実行されます。デフォルトで設定されるルールの制限によって、データベースに対する読み取りと書き込みが完全にできるのは、認証ユーザーだけです。これによってデータベースは不正行為から保護されます。ルールをカスタマイズするか、認証を設定するまで、この保護は継続します。
Firebase Database ルールの構文は JavaScript ライクで、次に示す 4 つの種類があります。
ルールの種類 | |
---|---|
.read | ユーザーによるデータの読み取りを許可するときに記述します。 |
.write | ユーザーによるデータの書き込みを許可するときに記述します。 |
.validate | 値の適切なフォーマット方法、子属性を持つかどうか、およびデータ型を定義します。 |
.indexOn | インデックスを作成する子に並べ替えとクエリをサポートするように指定します。 |
Realtime Database のセキュリティ概要
Firebase Realtime Database には、アプリのセキュリティを管理するための完全なツールセットが用意されています。これらのツールによって、ユーザーの認証、ユーザー権限の適用、入力内容の検証を簡単に実行できます。
Firebase のアプリは、その他多くの技術スタックを備えたアプリに比べて、クライアント側のコードを多く実行します。そのため、セキュリティにアプローチする方法が、場合によってこれまでとは少し異なります。
認証
アプリを保護する最初のセキュリティ手順は通常、ユーザーの識別です。このプロセスを「認証」と言います。 Firebase Authentication プロダクトを使用すると、ユーザーはアプリに簡単にログインできるようになります。Firebase Authentication は、Google や Facebook などの一般的な認証方法に加え、メールとパスワードでのログインや匿名ログインなどもサポートします。
ユーザー ID はセキュリティの重要な概念です。多様なユーザーがさまざまなデータを持ち、場合によっては多様な機能も持っています。たとえば、チャット アプリケーションでは、メッセージがそれぞれ作成したユーザーに関連付けられています。ユーザーは、自分のメッセージは削除できますが、他のユーザーが投稿したメッセージは削除できません。
承認
ユーザーの識別はセキュリティの一部にすぎません。ユーザーを識別したら、データに対するユーザーのアクセス権を制御する方法が必要になります。Firebase Database ルールによって、ユーザーごとにアクセス権を制御できます。たとえば、次のセキュリティ ルールセットでは、あらゆるユーザーがパス /foo/
を読み取ることはできますが、どのユーザーもこれに書き込むことはできません。
{ "rules": { "foo": { ".read": true, ".write": false } } }
.read
と .write
のルールはカスケード式に適用されます。そのため、このルールセットはパス /foo/
にあるあらゆるデータの読み取りアクセス権を付与するだけでなく、/foo/bar/baz
のようなより深いパスにあるデータの読み取りアクセス権も付与します。データベース内の浅いパスにある .read
や .write
のルールは、深いパスにあるルールよりも優先されるため、この例では、パス /foo/bar/baz
のルールが false と評価されても、/foo/bar/baz
への読み取りアクセス権は付与されます。
Firebase Database ルールには、他のパス、サーバー側のタイムスタンプ、認証情報などを参照できるようにする組み込みの変数と関数が用意されています。認証ユーザーに /users/<uid>/
への書き込みアクセス権を付与するルールの例を次に示します。ここで <uid>、は、Firebase Authentication によって取得されたユーザーの ID です。
{ "rules": { "users": { "$uid": { ".write": "$uid === auth.uid" } } } }
データの検証
Firebase Realtime Database はスキーマレスです。開発時の変更はこれで容易になりますが、アプリの配布準備ができてからは、データの一貫性が重要になります。ルール言語に含まれる .validate
ルールでは、.read
ルールや .write
ルールと同じ式によって検証ロジックを適用できます。唯一の違いは、検証ルールはカスケード式に適用されないことです。そのため、書き込みを許可するには、関連するすべての検証ルールの評価が true でなければなりません。
このルールにより、/foo/
に書き込まれるデータは 100 文字未満に制限されます。
{ "rules": { "foo": { ".validate": "newData.isString() && newData.val().length < 100" } } }
検証ルールでは、.read
ルールや .write
ルールと同じ組み込み関数や変数のすべてにアクセス権があります。これらによって、データベース内の他の場所にあるデータ、ユーザー ID、サーバー時間などを認識する検証ルールが作成できます。
データベース インデックスを定義する
Firebase Realtime Database ではデータの並べ替えとクエリを実行できます。データサイズが小さい場合、データベースがアドホック クエリをサポートしているため、通常、開発時にインデックスは必要ありません。ただしアプリを起動する前に、アプリの規模が拡大してもクエリが引き続き機能するように、クエリにインデックスを指定しておくことが重要です。
インデックスは .indexOn
ルールで指定します。
恐竜リストの体高フィールドと体長フィールドのインデックスを作成するインデックス宣言の例を次に示します。
{ "rules": { "dinosaurs": { ".indexOn": ["height", "length"] } } }