Firebase Summit で発表されたすべての情報をご覧ください。Firebase を使用してアプリ開発を加速し、自信を持ってアプリを実行する方法を紹介しています。詳細

Firebase CloudStorageのセキュリティルールの使用条件

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

このガイドは、Firebase セキュリティ ルール言語ガイドのコア構文の学習に基づいて作成されており、Cloud Storage の Firebase セキュリティ ルールに条件を追加する方法を示しています。

Cloud Storage セキュリティ ルールの主要な構成要素は条件です。条件は、特定の操作を許可するか拒否するかを決定するブール式です。基本的なルールでは、 truefalseリテラルを条件として使用すると、うまく機能します。ただし、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.authnullでないことを確認します
  • ユーザー非公開: 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値が含まれます。リクエストは書き込みです。 HTTP ヘッダーと認証状態も含まれます。

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には、 generationmetagenerationetagtimeCreated 、および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 セキュリティ ルールは、データの検証にも使用できます。これには、ファイル名とパス、およびcontentTypesizeなどのファイル メタデータ プロパティの検証が含まれます。

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 セキュリティ ルールで関数を使用すると、ルールの複雑さが増しても保守しやすくなります。

次のステップ

この条件の説明の後、ルールについてより高度な理解が得られ、次のことができるようになります。

コア ユース ケースの処理方法を学び、ルールの開発、テスト、デプロイのワークフローを学びます。