このガイドは、Firebase セキュリティ ルール言語ガイドのコア構文の学習に基づいて作成されており、Cloud Storage の Firebase セキュリティ ルールに条件を追加する方法を示しています。
Cloud Storage セキュリティ ルールの主要な構成要素は条件です。条件は、特定の操作を許可するか拒否するかを決定するブール式です。基本的なルールでは、 true
とfalse
リテラルを条件として使用すると、完全にうまく機能します。ただし、Cloud Storage 言語の Firebase セキュリティ ルールを使用すると、次のようなより複雑な条件を記述できます。
- ユーザー認証を確認する
- 受信データを検証する
認証
Cloud Storage の Firebase セキュリティ ルールは、Firebase Authentication と統合して、強力なユーザーベースの認証を Cloud Storage に提供します。これにより、Firebase Authentication トークンのクレームに基づく詳細なアクセス制御が可能になります。
認証されたユーザーが Cloud Storage に対してリクエストを実行すると、 request.auth
変数にユーザーのuid
( request.auth.uid
) と Firebase Authentication JWT のクレーム ( request.auth.token
) が入力されます。
さらに、カスタム認証を使用すると、追加のクレームがrequest.auth.token
フィールドに表示されます。
認証されていないユーザーがリクエストを実行すると、 request.auth
変数はnull
になります。
このデータを使用して、認証を使用してファイルを保護する一般的な方法がいくつかあります。
- 公開:
request.auth
無視 - 認証されたプライベート:
request.auth
がnull
でないことを確認します - ユーザー非公開:
request.auth.uid
がパスuid
と等しいことを確認します - グループ プライベート: カスタム トークンのクレームをチェックして選択したクレームと一致するか、ファイル メタデータを読み取ってメタデータ フィールドが存在するかどうかを確認します
公共
request.auth
コンテキストを考慮しないルールは、ユーザーの認証コンテキストを考慮しないため、 public
ルールと見なすことができます。これらのルールは、ゲーム アセット、サウンド ファイル、その他の静的コンテンツなどのパブリック データを表示する場合に役立ちます。
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
認証されたプライベート
場合によっては、アプリケーションのすべての認証済みユーザーがデータを表示できるようにする必要がありますが、認証されていないユーザーはデータを表示できないようにする必要があります。 request.auth
変数はすべての認証されていないユーザーに対してnull
であるため、認証を要求するためにrequest.auth
変数が存在することを確認するだけで済みます。
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
ユーザープライベート
request.auth
の最も一般的な使用例は、プロフィール写真のアップロードからプライベート ドキュメントの読み取りまで、個々のユーザーにファイルに対する詳細なアクセス許可を提供することです。
Cloud Storage 内のファイルにはファイルへの完全な「パス」があるため、ユーザーによって制御されるファイルを作成するために必要なのは、ファイル名のプレフィックス (ユーザーのuid
など) 内の一意のユーザー識別情報であり、これを確認できます。ルールが評価されるとき:
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth.uid == userId; }
グループプライベート
もう 1 つの同様に一般的な使用例は、複数のチーム メンバーが共有ドキュメントで共同作業できるようにするなど、オブジェクトに対するグループ権限を許可することです。これを行うには、いくつかの方法があります。
- グループ メンバーに関する追加情報(グループ ID など)を含む Firebase Authenticationカスタム トークンを作成する
- ファイルのメタデータにグループ情報 (グループ ID や許可された
uid
のリストなど) を含めます。
このデータがトークンまたはファイル メタデータに格納されると、ルール内から参照できます。
// Allow reads if the group ID in your token matches the file metadata's `owner` property // Allow writes if the group ID is in the user's custom token match /files/{groupId}/{fileName} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; }
評価を依頼する
アップロード、ダウンロード、メタデータの変更、削除は、Cloud Storage に送信されたrequest
を使用して評価されます。上記のrequest.auth
オブジェクト内のユーザーの一意の ID と Firebase Authentication ペイロードに加えて、 request
変数には、リクエストが実行されているファイル パス、リクエストが受信された時間、新しいresource
値が含まれます。リクエストは書き込みです。
request
オブジェクトには、 request.auth
オブジェクトにユーザーの一意の ID と Firebase Authentication ペイロードも含まれています。これについては、ドキュメントのユーザーベースのセキュリティセクションで詳しく説明します。
request
オブジェクトのプロパティの完全なリストは、以下で入手できます。
財産 | タイプ | 説明 |
---|---|---|
auth | map<文字列, 文字列> | ユーザーがログインすると、ユーザーの一意の ID であるuid と Firebase Authentication JWT クレームのマップであるtoken が提供されます。それ以外の場合はnull になります。 |
params | map<文字列, 文字列> | リクエストのクエリ パラメータを含むマップ。 |
path | 道 | リクエストが実行されているpath 表すパス。 |
resource | map<文字列, 文字列> | write リクエストのみに存在する新しいリソース値。 |
time | タイムスタンプ | リクエストが評価されるサーバー時間を表すタイムスタンプ。 |
リソース評価
ルールを評価するときに、アップロード、ダウンロード、変更、または削除されるファイルのメタデータを評価することもできます。これにより、特定のコンテンツ タイプのファイルのみをアップロードしたり、特定のサイズを超えるファイルのみを削除したりするなどの複雑で強力なルールを作成できます。
Cloud Storage の Firebase セキュリティ ルールは、 resource
オブジェクトでファイル メタデータを提供します。これには、Cloud Storage オブジェクトで表示されるメタデータのキーと値のペアが含まれます。これらのプロパティは、 read
またはwrite
要求で検査して、データの整合性を確保できます。
write
リクエスト (アップロード、メタデータの更新、削除など) では、リクエスト パスに現在存在するファイルのファイル メタデータを含むresource
オブジェクトに加えて、 request.resource
オブジェクトを使用することもできます。これには、書き込みが許可されている場合に書き込まれるファイル メタデータのサブセットが含まれます。これら 2 つの値を使用して、データの整合性を確保したり、ファイルの種類やサイズなどのアプリケーションの制約を適用したりできます。
resource
オブジェクトのプロパティの完全なリストを以下に示します。
財産 | タイプ | 説明 |
---|---|---|
name | ストリング | オブジェクトの完全な名前 |
bucket | ストリング | このオブジェクトが存在するバケットの名前。 |
generation | 整数 | このオブジェクトのGoogle Cloud Storage オブジェクトの世代。 |
metageneration | 整数 | このオブジェクトのGoogle Cloud Storage オブジェクトのメタ世代。 |
size | 整数 | オブジェクトのサイズ (バイト単位)。 |
timeCreated | タイムスタンプ | オブジェクトが作成された時刻を表すタイムスタンプ。 |
updated | タイムスタンプ | オブジェクトが最後に更新された時刻を表すタイムスタンプ。 |
md5Hash | ストリング | オブジェクトの MD5 ハッシュ。 |
crc32c | ストリング | オブジェクトの crc32c ハッシュ。 |
etag | ストリング | このオブジェクトに関連付けられた etag。 |
contentDisposition | ストリング | このオブジェクトに関連付けられたコンテンツの配置。 |
contentEncoding | ストリング | このオブジェクトに関連付けられたコンテンツ エンコーディング。 |
contentLanguage | ストリング | このオブジェクトに関連付けられたコンテンツの言語。 |
contentType | ストリング | このオブジェクトに関連付けられたコンテンツ タイプ。 |
metadata | map<文字列, 文字列> | 開発者が指定した追加のカスタム メタデータのキーと値のペア。 |
request.resource
には、 generation
、 metageneration
、 etag
、 timeCreated
、およびupdated
を除いて、これらすべてが含まれています。
Cloud Firestore で強化する
Cloud Firestore のドキュメントにアクセスして、他の承認基準を評価できます。
firestore.get()
() 関数とfirestore.exists()
関数を使用して、セキュリティ ルールは Cloud Firestore のドキュメントに対する受信リクエストを評価できます。 firestore.get()
およびfirestore.exists()
関数は両方とも、完全に指定されたドキュメント パスを想定しています。変数を使用してfirestore.get()
およびfirestore.exists()
) のパスを作成する場合、 $(variable)
構文を使用して変数を明示的にエスケープする必要があります。
以下の例では、ファイルへの読み取りアクセスを特定のクラブのメンバーであるユーザーに制限するルールを示しています。
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships } } }次の例では、ユーザーの友達だけが自分の写真を見ることができます。
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id)) } } }
これらの Cloud Firestore 機能を使用する最初の Cloud Storage セキュリティ ルールを作成して保存すると、Firebase コンソールまたは Firebase CLI で、2 つの製品を接続する権限を有効にするよう求められます。
Firebase セキュリティ ルールの管理とデプロイで説明されているように、IAM ロールを削除することで機能を無効にすることができます。
データを検証する
Cloud Storage の Firebase セキュリティ ルールは、データの検証にも使用できます。これには、ファイル名とパス、およびcontentType
やsize
などのファイル メタデータ プロパティの検証が含まれます。
service firebase.storage { match /b/{bucket}/o { match /images/{imageId} { // Only allow uploads of any image file that's less than 5MB allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*'); } } }
カスタム関数
Firebase セキュリティ ルールがより複雑になるにつれて、ルールセット全体で再利用できる関数で一連の条件をラップすることが必要になる場合があります。セキュリティ ルールは、カスタム関数をサポートしています。カスタム関数の構文は JavaScript に少し似ていますが、Firebase セキュリティ ルール関数はドメイン固有の言語で記述されており、いくつかの重要な制限があります。
- 関数には
return
ステートメントを 1 つだけ含めることができます。追加のロジックを含めることはできません。たとえば、ループを実行したり、外部サービスを呼び出したりすることはできません。 - 関数は、それらが定義されているスコープから関数と変数に自動的にアクセスできます。たとえば、
service firebase.storage
スコープ内で定義された関数はresource
変数にアクセスでき、Cloud Firestore の場合のみget()
やexists()
) などの組み込み関数にアクセスできます。 - 関数は他の関数を呼び出すことができますが、再帰はできません。呼び出しスタックの深さの合計は 10 に制限されています。
- バージョン
rules2
では、関数はlet
キーワードを使用して変数を定義できます。関数には任意の数の let バインディングを含めることができますが、return ステートメントで終了する必要があります。
関数はfunction
キーワードで定義され、0 個以上の引数を取ります。たとえば、上記の例で使用されている 2 種類の条件を 1 つの関数に組み合わせることができます。
service firebase.storage {
match /b/{bucket}/o {
// 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 /images/{imageId} {
allow read, write: if signedInOrPublic();
}
match /mp3s/{mp3Ids} {
allow read: if signedInOrPublic();
}
}
}
Firebase セキュリティ ルールで関数を使用すると、ルールの複雑さが増しても保守しやすくなります。
次のステップ
この条件の説明の後、ルールについてより高度な理解が得られ、次のことができるようになります。
コア ユース ケースの処理方法を学び、ルールの開発、テスト、デプロイのワークフローを学びます。
- 一般的なシナリオに対処するルールを記述します。
- 安全でないルールを見つけて回避しなければならない状況を確認して、知識を深めてください。
- Cloud Storage エミュレータと専用のセキュリティ ルール テスト ライブラリを使用してルールをテストします。
- ルールの展開に使用できる方法を確認します。