このガイドは、Firebase Security Rules言語ガイドのコア構文を学習して、CloudStorageのFirebaseSecurityRulesに条件を追加する方法を示しています。
ストレージセキュリティルールの主要な構成要素は条件です。条件は、特定の操作を許可するか拒否するかを決定するブール式です。基本的なルールの場合、条件としてtrue
およびfalse
リテラルを使用すると、問題なく機能します。ただし、クラウドストレージ言語のFirebaseセキュリティルールを使用すると、次のようなより複雑な条件を記述できます。
- ユーザー認証を確認する
- 受信データを検証する
認証
CloudStorageのFirebaseセキュリティルールはFirebaseAuthenticationと統合され、Google CloudStorageに強力なユーザーベースの認証を提供します。これにより、Firebase認証トークンの申し立てに基づいたきめ細かいアクセス制御が可能になります。
認証されたユーザーがrequest.auth
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
最も一般的な使用例は、プロフィール写真のアップロードからプライベートドキュメントの読み取りまで、個々のユーザーにファイルに対するきめ細かい権限を与えることです。
Google 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など)を含むFirebaseAuthenticationカスタムトークンを作成します
- ファイルメタデータにグループ情報(グループ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; }
評価をリクエストする
アップロード、ダウンロード、メタデータの変更、削除は、Google CloudStorageに送信されたrequest
を使用して評価されます。上記のrequest.auth
オブジェクト内のユーザーの一意のIDとFirebaseAuthenticationペイロードに加えて、 request
変数には、リクエストが実行されているファイルパス、リクエストが受信された時刻、および新しいresource
値が含まれます。リクエストは書き込みです。 HTTPヘッダーと認証状態も含まれています。
request
オブジェクトには、 request.auth
オブジェクトにユーザーの一意のIDとFirebase Authenticationペイロードも含まれています。これについては、ドキュメントの「ユーザーベースのセキュリティ」セクションで詳しく説明します。
request
オブジェクトのプロパティの完全なリストは、以下にあります。
プロパティ | タイプ | 説明 |
---|---|---|
auth | map <文字列、文字列> | ユーザーがログインすると、 uid 、ユーザーの一意のID、 token 、Firebase AuthenticationJWTが主張するマップを提供しuid 。それ以外の場合はnull になりnull 。 |
params | map <文字列、文字列> | リクエストのクエリパラメータを含むマップ。 |
path | 道 | リクエストが実行されているpath 表すパス。 |
resource | map <文字列、文字列> | write 要求にのみ存在する新しいリソース値。 |
time | タイムスタンプ | リクエストが評価されるサーバー時間を表すタイムスタンプ。 |
リソース評価
ルールを評価するときは、アップロード、ダウンロード、変更、または削除されるファイルのメタデータを評価することもできます。これにより、特定のコンテンツタイプのファイルのみをアップロードしたり、特定のサイズを超えるファイルのみを削除したりするなど、複雑で強力なルールを作成できます。
Cloud StorageのFirebaseセキュリティルールは、 resource
オブジェクトにファイルメタデータを提供します。これには、Google CloudStorageオブジェクトに表示されるメタデータのキーと値のペアが含まれます。これらのプロパティは、データの整合性を確保するために、 read
またはwrite
要求で検査できます。
write
リクエスト(アップロード、メタデータの更新、削除など)では、リクエストパスに現在存在するファイルのファイルメタデータを含むresource
オブジェクトに加えて、 request.resource
オブジェクトを使用することもできます。これには、書き込みが許可されている場合に書き込まれるファイルメタデータのサブセットが含まれています。これらの2つの値を使用して、データの整合性を確保したり、ファイルの種類やサイズなどのアプリケーションの制約を適用したりできます。
resource
オブジェクトのプロパティの完全なリストは、以下にあります。
プロパティ | タイプ | 説明 |
---|---|---|
name | ストリング | オブジェクトのフルネーム |
bucket | ストリング | このオブジェクトが存在するバケットの名前。 |
generation | int | このオブジェクトのGCSオブジェクト生成。 |
metageneration | int | このオブジェクトのGCSオブジェクトメタ生成。 |
size | int | オブジェクトのサイズ(バイト単位)。 |
timeCreated | タイムスタンプ | オブジェクトが作成された時刻を表すタイムスタンプ。 |
updated | タイムスタンプ | オブジェクトが最後に更新された時刻を表すタイムスタンプ。 |
md5Hash | ストリング | オブジェクトのMD5ハッシュ。 |
crc32c | ストリング | オブジェクトのcrc32cハッシュ。 |
etag | ストリング | このオブジェクトに関連付けられたetag。 |
contentDisposition | ストリング | このオブジェクトに関連付けられているコンテンツの配置。 |
contentEncoding | ストリング | このオブジェクトに関連付けられているコンテンツエンコーディング。 |
contentLanguage | ストリング | このオブジェクトに関連付けられているコンテンツ言語。 |
contentType | ストリング | このオブジェクトに関連付けられているコンテンツタイプ。 |
metadata | map <文字列、文字列> | 開発者が指定した追加のカスタムメタデータのキーと値のペア。 |
request.resource
は、 generation
、 metageneration
、 etag
、 timeCreated
、 metageneration
除いて、これらすべてが含まupdated
ます。
データを検証する
Cloud StorageのFirebaseセキュリティルールは、ファイル名とパス、 contentType
やsize
などのファイルメタデータプロパティの検証など、データの検証にも使用できcontentType
。
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 Security Rules関数は、いくつかの重要な制限があるドメイン固有言語で記述されています。
- 関数に含めることができる
return
ステートメントは1つだけです。追加のロジックを含めることはできません。たとえば、ループを実行したり、外部サービスを呼び出したりすることはできません。 - 関数は、それらが定義されているスコープから関数と変数に自動的にアクセスできます。たとえば、
service firebase.storage
スコープ内で定義された関数は、resource
変数にアクセスできます。CloudFirestoreの場合のみ、get()
やexists()
などの組み込み関数があり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セキュリティルールで関数を使用すると、ルールの複雑さが増すにつれて、関数のメンテナンスが容易になります。
次のステップ
この条件の説明の後、ルールをより高度に理解し、次の準備が整います。
コアユースケースを処理する方法を学び、ルールを開発、テスト、および展開するためのワークフローを学びます。
- 一般的なシナリオに対応するルールを作成します。
- 安全でないルールを見つけて回避する必要がある状況を確認することにより、知識を構築します。
- ルールの展開に使用できる方法を確認します。