Firebase セキュリティ ルールは、幅広い複雑さと粒度をサポートする柔軟で強力なカスタム言語を活用します。ルールは、アプリにとって意味のあるものとして具体的または一般的にすることができます。 Realtime Database ルールは、JSON 構造で JavaScript に似た構文を使用します。 Cloud Firestore と Cloud Storage のルールは、共通表現言語 (CEL)に基づく言語を使用します。CEL は、条件付きで許可されたアクセスをサポートするmatch
ステートメントとallow
ステートメントを使用して CEL に基づいています。
ただし、これらはカスタム言語であるため、習得には時間がかかります。このガイドを使用して、ルール言語をより深く理解し、より複雑なルールを深く掘り下げてください。
製品を選択して、そのルールの詳細を確認してください。
基本構造
クラウド ファイアストア
Cloud Firestore と Cloud Storage の Firebase セキュリティ ルールは、次の構造と構文を使用します。
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
ルールを構築する際には、次の重要な概念を理解することが重要です。
- Request:
allow
ステートメントで呼び出されるメソッド。これらは実行を許可するメソッドです。標準メソッドは、get
、list
、create
、update
、およびdelete
です。read
およびwrite
の便利なメソッドにより、指定されたデータベースまたはストレージ パスに対する広範な読み取りおよび書き込みアクセスが可能になります。 - パス: URI パスとして表されるデータベースまたはストレージの場所。
- ルール:要求が true と評価された場合に要求を許可する条件を含む
allow
ステートメント。
これらの概念のそれぞれについて、以下でさらに詳しく説明します。
クラウドストレージ
Cloud Firestore と Cloud Storage の Firebase セキュリティ ルールは、次の構造と構文を使用します。
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
ルールを構築する際には、次の重要な概念を理解することが重要です。
- Request:
allow
ステートメントで呼び出されるメソッド。これらは実行を許可するメソッドです。標準メソッドは、get
、list
、create
、update
、およびdelete
です。read
およびwrite
の便利なメソッドにより、指定されたデータベースまたはストレージ パスに対する広範な読み取りおよび書き込みアクセスが可能になります。 - パス: URI パスとして表されるデータベースまたはストレージの場所。
- ルール:要求が true と評価された場合に要求を許可する条件を含む
allow
ステートメント。
これらの概念のそれぞれについて、以下でさらに詳しく説明します。
リアルタイム データベース
Realtime Database では、Firebase セキュリティ ルールは、JSON ドキュメントに含まれる JavaScript に似た式で構成されます。
次の構文を使用します。
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
ルールには 3 つの基本要素があります。
- パス:データベースの場所。これは、データベースの JSON 構造を反映しています。
- リクエスト:これらは、ルールがアクセスを許可するために使用するメソッドです。
read
およびwrite
ルールは幅広い読み取りおよび書き込みアクセスを許可しますが、validate
ルールは受信データまたは既存のデータに基づいてアクセスを許可するための二次検証として機能します。 - 条件: true と評価された場合にリクエストを許可する条件。
規則の構造
クラウド ファイアストア
Cloud Firestore と Cloud Storage のルールの基本要素は次のとおりです。
-
service
宣言: ルールが適用される Firebase プロダクトを宣言します。 -
match
ブロック: ルールが適用されるデータベースまたはストレージ バケット内のパスを定義します。 -
allow
ステートメント: アクセスを許可するための条件を、メソッドによって区別して提供します。サポートされているメソッドには、get
、list
、create
、update
、delete
、および便利なメソッドread
とwrite
が含まれます。 - オプションの
function
宣言: 複数のルールで使用する条件を組み合わせてラップする機能を提供します。
service
には、リクエストへのアクセスを許可する条件を提供するallow
ステートメントを含む 1 つ以上のmatch
ブロックが含まれています。 request
変数とresource
変数は、ルール条件で使用できます。 Firebase セキュリティ ルール言語は、 function
宣言もサポートしています。
構文バージョン
syntax
ステートメントは、ソースの記述に使用された Firebase ルール言語のバージョンを示します。言語の最新バージョンはv2
です。
rules_version = '2';
service cloud.firestore {
...
}
rules_version
ステートメントが指定されていない場合、ルールはv1
エンジンを使用して評価されます。
サービス
service
宣言は、ルールが適用される Firebase プロダクトまたはサービスを定義します。ソース ファイルごとに 1 つのservice
宣言のみを含めることができます。
クラウド ファイアストア
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
クラウドストレージ
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Firebase CLI を使用して Cloud Firestore と Cloud Storage の両方のルールを定義している場合は、それらを別々のファイルで維持する必要があります。
マッチ
match
ブロックは、要求された操作のパス (着信request.path
) に対して一致するpath
パターンを宣言します。 match
の本体には、1 つ以上のネストされたmatch
ブロック、 allow
ステートメント、またはfunction
宣言が必要です。ネストされたmatch
ブロック内のパスは、親のmatch
ブロック内のパスに対して相対的です。
path
パターンは、変数またはワイルドカードを含むディレクトリのような名前です。 path
パターンにより、シングルパス セグメントとマルチパス セグメントの一致が可能になります。 path
にバインドされた変数は、 path
が宣言されているmatch
スコープまたはネストされたスコープ内で表示されます。
path
パターンに対する一致は、部分的または完全な場合があります。
- 部分一致:
path
パターンは、request.path
のプレフィックス一致です。 - 完全一致:
path
パターンはrequest.path
全体に一致します。
完全に一致すると、ブロック内のルールが評価されます。部分一致が行われると、ネストされたmatch
ルールがテストされ、ネストされたpath
が一致を完了するかどうかが確認されます。
各完全match
のルールが評価され、リクエストを許可するかどうかが決定されます。一致するルールがアクセスを許可する場合、リクエストは許可されます。アクセスを許可する一致するルールがない場合、リクエストは拒否されます。
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
上記の例が示すように、 path
宣言は次の変数をサポートします。
- 単一セグメントのワイルドカード:パスでワイルドカード変数を宣言するには、変数を中括弧
{variable}
で囲みます。この変数は、match
ステートメント内でstring
としてアクセスできます。 - 再帰的ワイルドカード:再帰的または複数セグメントのワイルドカードは、パスまたはその下の複数のパス セグメントに一致します。このワイルドカードは、設定した場所より下のすべてのパスに一致します。セグメント変数の末尾に
=**
文字列を追加することで宣言できます:{variable=**}
。この変数は、match
ステートメント内でpath
オブジェクトとしてアクセスできます。
許可する
match
ブロックには、1 つ以上のallow
ステートメントが含まれています。これらはあなたの実際のルールです。 allow
ルールを 1 つ以上のメソッドに適用できます。 Cloud Firestore または Cloud Storage が着信リクエストを許可するには、 allow
ステートメントの条件が true と評価される必要があります。 allow read
のように、条件なしでallow
ステートメントを記述することもできます。ただし、 allow
ステートメントに条件が含まれていない場合、そのメソッドの要求は常に許可されます。
メソッドのallow
ルールのいずれかが満たされている場合、リクエストは許可されます。さらに、より広範なルールがアクセスを許可する場合、ルールはアクセスを許可し、アクセスを制限する可能性のあるより細かいルールを無視します。
次の例を考えてみましょう。この例では、すべてのユーザーが自分のファイルを読み取ったり削除したりできます。より詳細なルールでは、書き込みを要求しているユーザーがファイルを所有しており、ファイルが PNG である場合にのみ、書き込みが許可されます。以前のルールで許可されているため、ユーザーは、PNG でなくても、サブパスにあるすべてのファイルを削除できます。
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
方法
各allow
ステートメントには、同じメソッドの着信要求に対するアクセスを許可するメソッドが含まれています。
方法 | リクエストの種類 |
---|---|
便利な方法 | |
read | あらゆる種類の読み取り要求 |
write | あらゆるタイプの書き込みリクエスト |
標準的な方法 | |
get | 単一のドキュメントまたはファイルの読み取り要求 |
list | クエリとコレクションの読み取り要求 |
create | 新しいドキュメントまたはファイルを書き込む |
update | 既存のデータベース ドキュメントへの書き込み、またはファイル メタデータの更新 |
delete | データを削除する |
同じmatch
ブロック内で読み取りメソッドをオーバーラップさせたり、同じpath
宣言内で競合する書き込みメソッドをオーバーラップさせたりすることはできません。
たとえば、次のルールは失敗します。
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
関数
セキュリティ ルールがより複雑になるにつれて、ルールセット全体で再利用できる関数で一連の条件をラップすることが必要になる場合があります。セキュリティ ルールは、カスタム関数をサポートしています。カスタム関数の構文は JavaScript に少し似ていますが、セキュリティ ルール関数はドメイン固有の言語で記述されており、いくつかの重要な制限があります。
- 関数には
return
ステートメントを 1 つだけ含めることができます。追加のロジックを含めることはできません。たとえば、ループを実行したり、外部サービスを呼び出したりすることはできません。 - 関数は、それらが定義されているスコープから関数と変数に自動的にアクセスできます。たとえば、
service cloud.firestore
スコープ内で定義された関数は、resource
変数とget()
やexists()
などの組み込み関数にアクセスできます。 - 関数は他の関数を呼び出すことができますが、再帰はできません。呼び出しスタックの深さの合計は 20 に制限されています。
- ルール バージョン
v2
では、関数はlet
キーワードを使用して変数を定義できます。関数には最大 10 個の let バインディングを含めることができますが、return ステートメントで終了する必要があります。
関数はfunction
キーワードで定義され、0 個以上の引数を取ります。たとえば、上記の例で使用されている 2 種類の条件を 1 つの関数に組み合わせることができます。
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
関数の引数と let の代入を示す例を次に示します。 Let 割り当てステートメントは、セミコロンで区切る必要があります。
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
isAdmin
割り当てが admins コレクションのルックアップを強制する方法に注意してください。不要なルックアップを必要としない遅延評価には、 &&
(AND) と||
の短絡的な性質を利用します。 (OR) isAuthor
が true ( &&
比較の場合) または false ( ||
比較の場合) である場合にのみ、2 番目の関数を呼び出すための比較。
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
セキュリティ ルールで関数を使用すると、ルールの複雑さが増しても保守しやすくなります。
クラウドストレージ
Cloud Firestore と Cloud Storage のルールの基本要素は次のとおりです。
-
service
宣言: ルールが適用される Firebase プロダクトを宣言します。 -
match
ブロック: ルールが適用されるデータベースまたはストレージ バケット内のパスを定義します。 -
allow
ステートメント: アクセスを許可するための条件を、メソッドによって区別して提供します。サポートされているメソッドには、get
、list
、create
、update
、delete
、および便利なメソッドread
とwrite
が含まれます。 - オプションの
function
宣言: 複数のルールで使用する条件を組み合わせてラップする機能を提供します。
service
には、リクエストへのアクセスを許可する条件を提供するallow
ステートメントを含む 1 つ以上のmatch
ブロックが含まれています。 request
変数とresource
変数は、ルール条件で使用できます。 Firebase セキュリティ ルール言語は、 function
宣言もサポートしています。
構文バージョン
syntax
ステートメントは、ソースの記述に使用された Firebase ルール言語のバージョンを示します。言語の最新バージョンはv2
です。
rules_version = '2';
service cloud.firestore {
...
}
rules_version
ステートメントが指定されていない場合、ルールはv1
エンジンを使用して評価されます。
サービス
service
宣言は、ルールが適用される Firebase プロダクトまたはサービスを定義します。ソース ファイルごとに 1 つのservice
宣言のみを含めることができます。
クラウド ファイアストア
service cloud.firestore {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
クラウドストレージ
service firebase.storage {
// Your 'match' blocks with their corresponding 'allow' statements and
// optional 'function' declarations are contained here
}
Firebase CLI を使用して Cloud Firestore と Cloud Storage の両方のルールを定義している場合は、それらを別々のファイルで維持する必要があります。
マッチ
match
ブロックは、要求された操作のパス (着信request.path
) に対して一致するpath
パターンを宣言します。 match
の本体には、1 つ以上のネストされたmatch
ブロック、 allow
ステートメント、またはfunction
宣言が必要です。ネストされたmatch
ブロック内のパスは、親のmatch
ブロック内のパスに対して相対的です。
path
パターンは、変数またはワイルドカードを含むディレクトリのような名前です。 path
パターンにより、シングルパス セグメントとマルチパス セグメントの一致が可能になります。 path
にバインドされた変数は、 path
が宣言されているmatch
スコープまたはネストされたスコープ内で表示されます。
path
パターンに対する一致は、部分的または完全な場合があります。
- 部分一致:
path
パターンは、request.path
のプレフィックス一致です。 - 完全一致:
path
パターンはrequest.path
全体に一致します。
完全に一致すると、ブロック内のルールが評価されます。部分一致が行われると、ネストされたmatch
ルールがテストされ、ネストされたpath
が一致を完了するかどうかが確認されます。
各完全match
のルールが評価され、リクエストを許可するかどうかが決定されます。一致するルールがアクセスを許可する場合、リクエストは許可されます。アクセスを許可する一致するルールがない場合、リクエストは拒否されます。
// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
// Partial match.
match /example/{singleSegment} { // `singleSegment` == 'hello'
allow write; // Write rule not evaluated.
// Complete match.
match /nested/path { // `singleSegment` visible in scope.
allow read; // Read rule is evaluated.
}
}
// Complete match.
match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
allow read; // Read rule is evaluated.
}
}
上記の例が示すように、 path
宣言は次の変数をサポートします。
- 単一セグメントのワイルドカード:パスでワイルドカード変数を宣言するには、変数を中括弧
{variable}
で囲みます。この変数は、match
ステートメント内でstring
としてアクセスできます。 - 再帰的ワイルドカード:再帰的または複数セグメントのワイルドカードは、パスまたはその下の複数のパス セグメントに一致します。このワイルドカードは、設定した場所より下のすべてのパスに一致します。セグメント変数の末尾に
=**
文字列を追加することで宣言できます:{variable=**}
。この変数は、match
ステートメント内でpath
オブジェクトとしてアクセスできます。
許可する
match
ブロックには、1 つ以上のallow
ステートメントが含まれています。これらはあなたの実際のルールです。 allow
ルールを 1 つ以上のメソッドに適用できます。 Cloud Firestore または Cloud Storage が着信リクエストを許可するには、 allow
ステートメントの条件が true と評価される必要があります。 allow read
のように、条件なしでallow
ステートメントを記述することもできます。ただし、 allow
ステートメントに条件が含まれていない場合、そのメソッドの要求は常に許可されます。
メソッドのallow
ルールのいずれかが満たされている場合、リクエストは許可されます。さらに、より広範なルールがアクセスを許可する場合、ルールはアクセスを許可し、アクセスを制限する可能性のあるより細かいルールを無視します。
次の例を考えてみましょう。この例では、すべてのユーザーが自分のファイルを読み取ったり削除したりできます。より詳細なルールでは、書き込みを要求しているユーザーがファイルを所有しており、ファイルが PNG である場合にのみ、書き込みが許可されます。以前のルールで許可されているため、ユーザーは、PNG でなくても、サブパスにあるすべてのファイルを削除できます。
service firebase.storage {
// Allow the requestor to read or delete any resource on a path under the
// user directory.
match /users/{userId}/{anyUserFile=**} {
allow read, delete: if request.auth != null && request.auth.uid == userId;
}
// Allow the requestor to create or update their own images.
// When 'request.method' == 'delete' this rule and the one matching
// any path under the user directory would both match and the `delete`
// would be permitted.
match /users/{userId}/images/{imageId} {
// Whether to permit the request depends on the logical OR of all
// matched rules. This means that even if this rule did not explicitly
// allow the 'delete' the earlier rule would have.
allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
}
}
方法
各allow
ステートメントには、同じメソッドの着信要求に対するアクセスを許可するメソッドが含まれています。
方法 | リクエストの種類 |
---|---|
便利な方法 | |
read | あらゆる種類の読み取り要求 |
write | あらゆるタイプの書き込みリクエスト |
標準的な方法 | |
get | 単一のドキュメントまたはファイルの読み取り要求 |
list | クエリとコレクションの読み取り要求 |
create | 新しいドキュメントまたはファイルを書き込む |
update | 既存のデータベース ドキュメントへの書き込み、またはファイル メタデータの更新 |
delete | データを削除する |
同じmatch
ブロック内で読み取りメソッドをオーバーラップさせたり、同じpath
宣言内で競合する書き込みメソッドをオーバーラップさせたりすることはできません。
たとえば、次のルールは失敗します。
service bad.example {
match /rules/with/overlapping/methods {
// This rule allows reads to all authenticated users
allow read: if request.auth != null;
match another/subpath {
// This secondary, more specific read rule causes an error
allow get: if request.auth != null && request.auth.uid == "me";
// Overlapping write methods in the same path cause an error as well
allow write: if request.auth != null;
allow create: if request.auth != null && request.auth.uid == "me";
}
}
}
関数
セキュリティ ルールがより複雑になるにつれて、ルールセット全体で再利用できる関数で一連の条件をラップすることが必要になる場合があります。セキュリティ ルールは、カスタム関数をサポートしています。カスタム関数の構文は JavaScript に少し似ていますが、セキュリティ ルール関数はドメイン固有の言語で記述されており、いくつかの重要な制限があります。
- 関数には
return
ステートメントを 1 つだけ含めることができます。追加のロジックを含めることはできません。たとえば、ループを実行したり、外部サービスを呼び出したりすることはできません。 - 関数は、それらが定義されているスコープから関数と変数に自動的にアクセスできます。たとえば、
service cloud.firestore
スコープ内で定義された関数は、resource
変数とget()
やexists()
などの組み込み関数にアクセスできます。 - 関数は他の関数を呼び出すことができますが、再帰はできません。呼び出しスタックの深さの合計は 20 に制限されています。
- ルール バージョン
v2
では、関数はlet
キーワードを使用して変数を定義できます。関数には最大 10 個の let バインディングを含めることができますが、return ステートメントで終了する必要があります。
関数はfunction
キーワードで定義され、0 個以上の引数を取ります。たとえば、上記の例で使用されている 2 種類の条件を 1 つの関数に組み合わせることができます。
service cloud.firestore {
match /databases/{database}/documents {
// True if the user is signed in or the requested data is 'public'
function signedInOrPublic() {
return request.auth.uid != null || resource.data.visibility == 'public';
}
match /cities/{city} {
allow read, write: if signedInOrPublic();
}
match /users/{user} {
allow read, write: if signedInOrPublic();
}
}
}
関数の引数と let の代入を示す例を次に示します。 Let 割り当てステートメントは、セミコロンで区切る必要があります。
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
return isAuthor || isAdmin;
}
isAdmin
割り当てが admins コレクションのルックアップを強制する方法に注意してください。不要なルックアップを必要としない遅延評価には、 &&
(AND) と||
の短絡的な性質を利用します。 (OR) isAuthor
が true ( &&
比較の場合) または false ( ||
比較の場合) である場合にのみ、2 番目の関数を呼び出すための比較。
function isAdmin(userId) {
return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
let isAuthor = article.author == userId;
// `||` is short-circuiting; isAdmin called only if isAuthor == false.
return isAuthor || isAdmin(userId);
}
セキュリティ ルールで関数を使用すると、ルールの複雑さが増しても保守しやすくなります。
リアルタイム データベース
前述のとおり、Realtime Database ルールには 3 つの基本要素が含まれます。データベースの JSON 構造のミラーとしてのデータベースの場所、リクエスト タイプ、およびアクセスを許可する条件です。
データベースの場所
ルールの構造は、データベースに保存したデータの構造に従う必要があります。たとえば、メッセージのリストを含むチャット アプリでは、次のようなデータがあるとします。
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
ルールはその構造を反映する必要があります。例えば:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) &&
newData.child('content').isString() &&
newData.child('timestamp').isNumber()"
}
}
}
}
上記の例が示すように、Realtime Database ルールは、パス セグメントに一致する$location
変数をサポートしています。パス セグメントの前に$
プレフィックスを使用して、ルールをパスに沿った子ノードに一致させます。
{
"rules": {
"rooms": {
// This rule applies to any child of /rooms/, the key for each room id
// is stored inside $room_id variable for reference
"$room_id": {
"topic": {
// The room's topic can be changed if the room id has "public" in it
".write": "$room_id.contains('public')"
}
}
}
}
}
$variable
を定数パス名と並行して使用することもできます。
{
"rules": {
"widget": {
// a widget can have a title or color attribute
"title": { ".validate": true },
"color": { ".validate": true },
// but no other child paths are allowed
// in this case, $other means any key excluding "title" and "color"
"$other": { ".validate": false }
}
}
}
方法
Realtime Database には、3 種類のルールがあります。これらのルール タイプのうち、 read
とwrite
の 2 つは、着信要求のメソッドに適用されます。 validate
ルール タイプは、データ構造を適用し、データの形式と内容を検証します。ルールは、 .write
ルールがアクセスを許可することを確認した後、 .validate
ルールを実行します。
ルールの種類 | |
---|---|
。読む | ユーザーによるデータの読み取りが許可されているかどうか、およびいつ許可されているかを示します。 |
。書きます | データの書き込みが許可されているかどうか、およびいつ許可されているかについて説明します。 |
。検証 | 正しくフォーマットされた値がどのように見えるか、子属性を持つかどうか、およびデータ型を定義します。 |
デフォルトでは、それを許可するルールがない場合、パスでのアクセスは拒否されます。
建物条件
クラウド ファイアストア
条件は、特定の操作を許可するか拒否するかを決定するブール式です。 request
変数とresource
変数は、これらの条件のコンテキストを提供します。
request
変数
request
変数には、次のフィールドと対応する情報が含まれます。
request.auth
Firebase Authentication からの認証資格情報を含む JSON Web トークン (JWT)。 auth
トークンには、一連の標準クレームと、Firebase Authentication で作成したカスタム クレームが含まれています。 Firebase セキュリティ ルールと認証の詳細については、こちらをご覧ください。
request.method
request.method
は、標準メソッドまたはカスタム メソッドのいずれかです。すべての読み取り専用またはすべての書き込み専用の標準メソッドにそれぞれ適用される書き込み規則を単純化するために、便利なメソッドread
およびwrite
も存在します。
request.params
request.params
には、 request.resource
に特に関連しないデータが含まれており、評価に役立つ可能性があります。実際には、このマップはすべての標準メソッドで空にする必要があり、カスタム メソッドの非リソース データを含める必要があります。サービスは、params として提示されたキーと値の名前を変更したり、タイプを変更したりしないように注意する必要があります。
request.path
request.path
は、ターゲットresource
のパスです。パスはサービスに対する相対パスです。 /
などの非 URL セーフ文字を含むパス セグメントは、URL エンコードされます。
resource
変数
resource
は、キーと値のペアのマップとして表されるサービス内の現在の値です。条件内でresource
を参照すると、サービスから値が最大 1 回読み取られます。このルックアップは、リソースのサービス関連のクォータに対してカウントされます。 get
リクエストの場合、 resource
は拒否時のクォータにのみカウントされます。
演算子と演算子の優先順位
Cloud Firestore と Cloud Storage のルールの演算子と対応する優先順位については、以下の表を参照してください。
任意の式a
およびb
、フィールドf
、およびインデックスi
が与えられます。
オペレーター | 説明 | 結合性 |
---|---|---|
a[i] a() af | インデックス、呼び出し、フィールド アクセス | 左から右へ | !a -a | 単項否定 | 右から左へ |
a/ba%ba*b | 乗法演算子 | 左から右へ |
a+b ab | 加算演算子 | 左から右へ |
a>ba>=ba | 関係演算子 | 左から右へ |
a in b | リストまたはマップに存在 | 左から右へ |
a is type | 型比較。 type は bool、int、float、number、string、list、map、timestamp、duration、path、latlng のいずれかです | 左から右へ |
a==ba!=b | 比較演算子 | 左から右へ | a && b | 条件付き AND | 左から右へ |
a || b | 条件付き OR | 左から右へ |
a ? true_value : false_value | 三項式 | 左から右へ |
クラウドストレージ
条件は、特定の操作を許可するか拒否するかを決定するブール式です。 request
変数とresource
変数は、これらの条件のコンテキストを提供します。
request
変数
request
変数には、次のフィールドと対応する情報が含まれます。
request.auth
Firebase Authentication からの認証資格情報を含む JSON Web トークン (JWT)。 auth
トークンには、一連の標準クレームと、Firebase Authentication で作成したカスタム クレームが含まれています。 Firebase セキュリティ ルールと認証の詳細については、こちらをご覧ください。
request.method
request.method
は、標準メソッドまたはカスタム メソッドのいずれかです。すべての読み取り専用またはすべての書き込み専用の標準メソッドにそれぞれ適用される書き込み規則を単純化するために、便利なメソッドread
およびwrite
も存在します。
request.params
request.params
には、 request.resource
に特に関連しないデータが含まれており、評価に役立つ可能性があります。実際には、このマップはすべての標準メソッドで空にする必要があり、カスタム メソッドの非リソース データを含める必要があります。サービスは、params として提示されたキーと値の名前を変更したり、タイプを変更したりしないように注意する必要があります。
request.path
request.path
は、ターゲットresource
のパスです。パスはサービスに対する相対パスです。 /
などの非 URL セーフ文字を含むパス セグメントは、URL エンコードされます。
resource
変数
resource
は、キーと値のペアのマップとして表されるサービス内の現在の値です。条件内でresource
を参照すると、サービスから値が最大 1 回読み取られます。このルックアップは、リソースのサービス関連のクォータに対してカウントされます。 get
リクエストの場合、 resource
は拒否時のクォータにのみカウントされます。
演算子と演算子の優先順位
Cloud Firestore と Cloud Storage のルールの演算子と対応する優先順位については、以下の表を参照してください。
任意の式a
およびb
、フィールドf
、およびインデックスi
が与えられます。
オペレーター | 説明 | 結合性 |
---|---|---|
a[i] a() af | インデックス、呼び出し、フィールド アクセス | 左から右へ | !a -a | 単項否定 | 右から左へ |
a/ba%ba*b | 乗法演算子 | 左から右へ |
a+b ab | 加算演算子 | 左から右へ |
a>ba>=ba | 関係演算子 | 左から右へ |
a in b | リストまたはマップに存在 | 左から右へ |
a is type | 型比較。 type は bool、int、float、number、string、list、map、timestamp、duration、path、latlng のいずれかです | 左から右へ |
a==ba!=b | 比較演算子 | 左から右へ | a && b | 条件付き AND | 左から右へ |
a || b | 条件付き OR | 左から右へ |
a ? true_value : false_value | 三項式 | 左から右へ |
リアルタイム データベース
条件は、特定の操作を許可するか拒否するかを決定するブール式です。これらの条件は、次の方法で Realtime Database ルールで定義できます。
定義済み変数
ルール定義内でアクセスできる便利な定義済み変数が多数あります。それぞれの概要は次のとおりです。
定義済み変数 | |
---|---|
今 | Linux エポックからの現在の時間 (ミリ秒)。これは、SDK の firebase.database.ServerValue.TIMESTAMP で作成されたタイムスタンプの検証に特に適しています。 |
根 | 試行された操作の前に存在する Firebase データベースのルート パスを表すRuleDataSnapshot 。 |
新しいデータ | 試行された操作後に存在するデータを表すRuleDataSnapshot 。これには、書き込まれる新しいデータと既存のデータが含まれます。 |
データ | 試行された操作の前に存在していたデータを表すRuleDataSnapshot 。 |
$変数 | ID と動的な子キーを表すために使用されるワイルドカード パス。 |
認証 | 認証されたユーザーのトークン ペイロードを表します。 |
これらの変数は、ルールのどこでも使用できます。たとえば、次のセキュリティ ルールは、 /foo/
ノードに書き込まれるデータが 100 文字未満の文字列でなければならないことを保証します。
{ "rules": { "foo": { // /foo is readable by the world ".read": true, // /foo is writable by the world ".write": true, // data written to /foo must be a string less than 100 characters ".validate": "newData.isString() && newData.val().length < 100" } } }
データベースのルール
データベース内のすべてのデータをルールで使用できます。定義済みの変数root
、 data
、およびnewData
を使用すると、書き込みイベントの前後に存在する任意のパスにアクセスできます。
/allow_writes/
ノードの値がtrue
で、親ノードにreadOnly
フラグが設定されておらず、新しく書き込まれたデータにfoo
という名前の子がある限り、書き込み操作を許可する次の例を検討してください。
".write": "root.child('allow_writes').val() === true && !data.parent().child('readOnly').exists() && newData.child('foo').exists()"
クエリベースのルール
ルールをフィルターとして使用することはできませんが、ルールでクエリ パラメーターを使用することにより、データのサブセットへのアクセスを制限できます。 query.
式をルールに追加して、クエリ パラメータに基づいて読み取りまたは書き込みアクセスを許可します。
たとえば、次のクエリ ベースのルールは、ユーザー ベースのセキュリティ ルールとクエリ ベースのルールを使用して、 baskets
コレクション内のデータへのアクセスを、アクティブなユーザーが所有するショッピング バスケットのみに制限します。
"baskets": {
".read": "auth.uid !== null &&
query.orderByChild === 'owner' &&
query.equalTo === auth.uid" // restrict basket access to owner of basket
}
ルールにクエリ パラメータを含む次のクエリは成功します。
db.ref("baskets").orderByChild("owner")
.equalTo(auth.currentUser.uid)
.on("value", cb) // Would succeed
ただし、ルールにパラメーターが含まれていないクエリは、 PermissionDenied
エラーで失敗します。
db.ref("baskets").on("value", cb) // Would fail with PermissionDenied
クエリベースのルールを使用して、読み取り操作によってクライアントがダウンロードするデータの量を制限することもできます。
たとえば、次のルールは、優先順位に従って、クエリの最初の 1000 件の結果のみに読み取りアクセスを制限します。
messages: {
".read": "query.orderByKey &&
query.limitToFirst <= 1000"
}
// Example queries:
db.ref("messages").on("value", cb) // Would fail with PermissionDenied
db.ref("messages").limitToFirst(1000)
.on("value", cb) // Would succeed (default order by key)
次のquery.
式は Realtime Database ルールで使用できます。
クエリベースのルール式 | ||
---|---|---|
表現 | タイプ | 説明 |
query.orderByKey query.orderByPriority query.orderByValue | ブール値 | キー、優先度、または値で並べ替えられたクエリの場合は true。それ以外の場合は偽。 |
query.orderByChild | ストリング ヌル | 文字列を使用して、子ノードへの相対パスを表します。たとえば、 query.orderByChild === "address/zip" です。クエリが子ノードによって順序付けられていない場合、この値は null です。 |
query.startAt query.endAt query.equalTo | ストリング 番号 ブール値 ヌル | 実行中のクエリの境界を取得するか、境界セットがない場合は null を返します。 |
query.limitToFirst query.limitToLast | 番号 ヌル | 実行中のクエリの制限を取得するか、制限が設定されていない場合は null を返します。 |
オペレーター
Realtime Database ルールは、条件ステートメントで変数を結合するために使用できる多数の演算子をサポートしています。演算子の完全なリストについては、リファレンス ドキュメント を参照してください。
条件の作成
実際の条件は、付与するアクセスによって異なります。ルールは意図的に非常に高い柔軟性を提供するため、アプリのルールは最終的に必要に応じて単純にも複雑にもできます。
シンプルで本番環境に対応したルールを作成するためのガイダンスについては、「基本的なセキュリティ ルール」を参照してください。