ユーザーデータを保護する

Cloud Storage 用の Firebase Security RulesFirebase Authentication と統合すると、Cloud Storage にユーザーベースの強力な認証を実装できます。これにより、Firebase Authentication トークンのクレームに基づいてアクセスを細かく制御することができます。

ユーザー認証

認証されたユーザーが Cloud Storage に対してリクエストを行うと、request.auth 変数にユーザーの uidrequest.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 != null && request.auth.uid == userId;
}

グループ非公開

ユーザー非公開と同じくらい一般的な使用例として挙げられるのが、オブジェクトに対するグループ アクセス権限を許可することです。たとえば、共有ドキュメント上での共同編集を複数のチームメンバーに許可します。これを行う方法はいくつかあります。

  • グループ メンバーに関する追加情報(グループ 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;
}

一般的な 4 つの認証制限の簡単な使用例を以下に示します。

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Anyone can view any image (no auth, publicly readable)
      match /{allImages=**} {
        allow read;
      }

      // Only authenticated users can write to "public" images
      match /public/{imageId} {
        allow write: if request.auth != null;
      }

      // Only an individual user can write to "their" images
      match /{userId}/{imageId} {
        allow write: if request.auth.uid == userId;
      }

      // Allow a "group" of users to read/write to shared images
      // An owner metadata property on the object contains the groupId for reads
      // A custom token has been minted with a groupId property for writes
      match /{groupId}/{imageId} {
        allow read: if resource.metadata.owner == request.auth.token.groupId;
        allow write: if request.auth.token.groupId == groupId;
      }
    }
  }
}