Firebaseのデータベースのセキュリティルールの書き方 グループ編

記事
IT・テクノロジー

Firebaseのデータベースのセキュリティルールの書き方 グループ編

Firebase のデータベースのセキュリティルールの具体的な書き方を紹介していきます。 今回はグループ単位でセキュリティルールを管理する場合の例について紹介します。

基本のルール

Firebase のプロジェクトを作成して、Cloud Firestore のデータベースを作成すると、最初にルールを設定するように言われます。 基本的な選択肢は2つです

* プロダクションモード(production mode)
* テストモード(test mode)
通常はこのどちらかを選択して開発を始めます。

プロダクションモード

プロダクションモードは基本的に全てのアクセスが禁止になっています。 必要に応じて、アクセスの権限を設定する必要があります。

以下のルールが標準設定のプロダクションモードになります。 この状態では、データベースのアクセスはできません。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

テストモード

テストモードの場合は、基本的に全てのアクセスが許可されています。 インターネットに公開しないで、開発する場合は、このモードを使うとまずは開発の基本的な機能の開発に集中できます。期限をつけて許可をしているので設定した日時(通常はデータベースを作成してから 30 日間)を過ぎるとアクセスができなくなります。

以下のルールが標準設定のテストモードです。 この状態では、データベースの全てのデータにアクセスできるので、この状態でインターネットに公開するのは危険です。インターネットに公開していない場合は、Firebase のプロジェクト情報が漏れなければアクセスするのは難しくなります。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if
          request.time < timestamp.date(2021, 3, 18);
    }
  }
}

ルール設定の基本

まずはルール設定の基本から説明していきます。

基本的なセキュリティルールのポリシーは Firebase のデータベースのアクセスを「全て許可」するルールは作らない事です。

match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: true;
    }
  }
この状態だと、誰でも該当する Firebase のプロジェクトのデータベースの全てのアクセスが可能になるのでインターネットにこの状態で公開するのは危険です。

例外的に全てのアクセスを認める場合は、「管理者」だけです。 管理用のアプリを作成しない場合は、Firebase コンソールか Web アプリに管理者モードを作ることになります。その場合は、管理者として Firebase の認証をしたユーザーのみに認めるようにします。

さらに高いセキュリティが必要な場合は、管理用のアプリを作成して、管理用の PC から実行できるようにして、インターネットに公開しない方法の方がより安全に管理が可能です。この場合は、Firebase admin SDK を利用すれば、セキュリティルールでアクセスの権限を設定する必要はありません。

管理者モードを作る場合

管理者モードを作る場合は、Firebase のユーザー ID を基にアクセスの権限を設定します。

以下のように、設定するとユーザー ID(uid)が「SHBzgQgRwnS4OdQaroNG5BOJG1i1」のユーザのみが Firebase のデータベースの全てのアクセスが許可されます。管理者の uid を使えば管理者モードになります。

match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if (request.auth.uid == "SHBzgQgRwnS4OdQaroNG5BOJG1i1");
    }
  }

一般利用者に対する設定

一般の利用者のアクセス権限に関する設定は、アクセスが必要な「コレクション」「ドキュメント」毎に設定するようにした方が安全です。

以下のように設定すると、「DataCollection0」のコレクションの全てのドキュメントに Firebase のユーザー認証(ログイン)をしたユーザは読み込みができるという設定です。

match /databases/{database}/documents {
    match /DataCollection0/{collection0_doc} {
        allow read: if (request.auth.uid != null);
    }

}

グループ毎の設定

さて、ここでこの記事の本題、「グループ」事の設定をどうするかを考えてみます。 Firebase のセキュリティルールで簡単に取得できるユーザー関連の情報は

* ユーザー ID(uid)
* E-Mail アドレス(email) 

利用する、ユーザー認証によって取得できる情報が多少違いますが、基本的には上に挙げた情報になります。それ以外の情報は基本的には取得できません。

従って、この情報だけでグループ毎の権限を設定しようとすると、グループの E-Mail アドレスを一つ一つチェックする事になってしまいます。これは少し面倒です。

そこで、Firebase のデータベースの情報を利用するとセキュリティルールの設定をシンプルにする事ができます。

Firebase のデータベースに「users」というコレクションを作って以下のような JSON の情報を入れるようにします。

{
  "name": "ユーザーの名前",
  "uid": "ユーザーID",
  "gid": "グループID",
  "email": "E-Mailアドレス"
}
このデータを作成する際に、グループを識別するための「gid」を割り当てておくと、これをセキュリティルールから利用する事ができます。

以下がセキュリティルールの例です。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
   // Gets a user entry
   function get_user_entry(uid) {
     return get(/databases/$(database)/documents/users/$(uid));
    }
    match /DataCollection2/{collection2_data {
        read: if get_user_entry(request.auth.uid) == "xxxx";
    }
  }
「get_user_entry(uid)」という関数をセキュリティルールで作ります。 この関数は、uid を基にユーザー情報が入ったドキュメントをセキュリティルール内で取得する関数です。ドキュメント ID とユーザー ID が一致するように作成しするようにします。

あとは、このグループ ID を基にアクセスの権限を設定すれば、ユーザー ID を羅列するよりはシンプルで見やすいセキュリティルールを作る事ができます。

まとめ
Firebase のデータベースのアクセスのためのセキュリティルールの具体的な書き方を紹介しています。 この記事では、グループ毎にアクセスの設定をどうしたら、シンプルでわかりやすいルールを書けるかを紹介しています。

グループのユーザー ID を一つ一つチェックする方法も可能ですが、グループの人数が多くなると、セキュリティルール自体が見づらくなりますし、変更も大変です。

今回紹介した方法は、Firebase のデータベースをセキュリティルールから利用する方法です。この方法を使うと、データベースにカスタムのユーザー情報を持つことで、その情報をセキュリティルールで利用できます。


サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す