The Round

合同会社ナイツオの開発ブログ

[PR] 5分から相談できるGCP™ 開発コンサル!→こちら

Firebaseでチャットアプリを作る日記(7日目)〜 Firestore セキュリティルールを書く

モバイルやWEBのClient LibraryからFirestoreにアクセスする場合、ユーザーがどのデータを参照・更新可能か、セキュリティルールを設定しておく必要があります。

ちなみに現在はFirestore初期化時に「テストモード」を選択した為下記の様になっています。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // This rule allows anyone on the internet to view, edit, and delete
    // all data in your Firestore database. It is useful for getting
    // started, but it is configured to expire after 30 days because it
    // leaves your app open to attackers. At that time, all client
    // requests to your Firestore database will be denied.
    //
    // Make sure to write security rules for your app before that time, or else
    // your app will lose access to your Firestore database
    match /{document=**} {
      allow read, write: if request.time < timestamp.date(2020, 1, 12);
    }
  }
}

最初の30日間は参照、書き込み自由でその後は全て拒否するようになっています。 これを適切な設定で上書きします。

許可はかなり注意しないと簡単にセキュリティインシデント起こしそうです。 (例えばブラウザコンソールからJavascriptAPI実行して不正に更新したり、他人のデータ覗いたり)

roomsのセキュリティルール設定

改めて、roomドキュメントのデータ構造は下記の様になっています。

プロパティ 説明
name string ルーム名
owner string 作成ユーザー
members array 参加者リスト

今回以下の様なルールを設定します。

  • 新規登録はサインイン済ユーザーがownerになっている場合のみ
  • membersにもサインイン済ユーザーが含まれていること
  • 更新(UPDATE)はとりあえずなし
  • 参照はmembersフィールド(array)にサインイン済ユーザーが含まれていること

上記を踏まえて、下記の様に設定しました。

firebase init で生成されたファイル firestore.rules を修正します。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    match /rooms/{room} {
      allow create: if request.auth.uid != null &&
        request.auth.token.email_verified && 
        request.auth.token.email == request.resource.data.owner && 
        request.auth.token.email in request.resource.data.members;
      allow read: if request.auth.uid != null &&
        request.auth.token.email_verified &&
        request.auth.token.email in resource.data.members;
    }
  }
}

ざっくり解説

  • allow create - 新規保存を許可。create の他に update delete と、全ての更新系をまとめた write という権限があります

  • allow read - 参照を許可。 get list をまとめた権限です

  • request.auth.uid != null - サインイン済であること

  • request.auth.token.email == request.resource.data.owner - ユーザーのemailアドレスが保存しようとしているroomドキュメントのownerフィールドに設定されていること

  • request.auth.token.email in request.resource.data.members - ユーザーのemailアドレスが保存しようとしているroomドキュメントのmembersフィールド(array)に含まれていること

  • request.auth.token.email_verified - ユーザーのemailアドレスがverify済であること

  • request.auth.token.email in resource.data.members - ユーザーのemailアドレスが参照しようとしているroomドキュメントのmembersフィールドに含まれていること

セキュリティルールのデプロイ

下記コマンドを実行します。

$ firebase deploy --only firestore:rules

セキュリティルールのテスト

Firebaeコンソールサイドバー「Database」→「ルール」タブのシミュレータで、セキュリティルールのテスト(シミュレーション)を行うことができます。

シミュレーションタイプ(get, create, update, delete)や認証情報、更新データなど細かく指定して、操作可能かどうかをチェックすることができます。

f:id:knightso:20191219173009j:plain

かなり便利です\(^o^)/

これ、ルールをデプロイせずにチェックすることはできないのでしょうか。。

まとめ

本日は Firestore のセキュリティルールを設定しました。

セキュリティルール、今回は少し調べただけですが、ルール内で他のドキュメントを参照したり等、かなり柔軟な設定ができそうです(^_^)

いずれもっと掘り下げてみたいと思います。