Firebase書き込みの為のセキュリティールール

記事
IT・テクノロジー

Firebase書き込みの為のセキュリティールール

Firebase のデータベース(Cloud Firestore)の読み込みの権限を設定するセキュリティルールは比較的シンプルなのでわかりやすいと思います。しかし、書き込みの場合少し複雑です。

この記事では、Firebase のデータベース(Cloud Firestore)への書き込みの為の権限の設定を行うセキュリティルールについて基本事項をまとめてみました。

Firebase のデータベースへの書き込みアクセス

Firebase のデータベース(Cloud Firestore)への書き込みの為のセキュリティルールを考える前に、まず、Firebase のデータベース(Cloud Firestore)への書き込みアクセスについて確認しておきます。

Firebase のデータベース(Cloud Firestore)への書き込みアクセスは大きく3つの種類があります。

* 新規作成(新たにドキュメントを追加する)- create
* 更新(既存のドキュメントのデータの更新)- update
* 削除(既存のドキュメントを削除)- delete
Firebase のセキュリティルールは「読み込み(read)」と「書き込み(write)」を分けて設定できますが、書き込みの権限はさらに上に挙げた分類毎に設定できます。

アプリケーションによって必要な権限が変わります!

Firebase のデータベースのアクセス権限は、開発するアプリケーションによって必要な権限や設定が変わってきます。まずは、開発するアプリケーションについて「誰が」「どんなアクセス」を必要とするのかを考えることか始めます。

お問い合わせフォームのサービスの場合

まずは、シンプルな例としてお問い合わせフォームの Web サービスをする場合を考えてみます。サービスの内容は、利用者が問い合わせたい内容を入力フォームに記入して、回答の担当者に送付するというサービスです。Web サイトの運営側(管理者)は、送付されたお問い合わせを確認して、必要な回答をします。また、処理が終わって不要になったお問い合わせ内容を削除も Web サイトの運営側で行います。

この場合必要なユーザーのタイプは2種類です。

* 一般の Web サイトの利用者
* Web サイト(アプリ)の管理者
このサービスで必要な Firebase のデータベース(Cloud Firestore)へのアクセスは

* お問い合わせ内容の送付(データベースのドキュメントの新規作成)
* お問い合わせ内容の確認(データベースのドキュメントの読み込み)
* お問い合わせ内容の削除(データベースのドキュメントの削除)
* お問い合わせ内容の更新は行わない
これをユーザーのタイプで分類すると

一般利用者:読み込み禁止、新規作成許可、削除禁止、更新は使わない
管理者:読み込み許可、新規作成はどちらでも可、削除許可、更新は使わない

のようになります。 基本的に、利用者は、お問い合わせを投稿できますが、他の人の投稿したお問い合わせ内容は見ることができませんし、更新や削除もできないようにしています。 一方で管理者は、お問い合わせ内容を読み込んだり、削除できるようにしています。管理者の場合は新規作成の権限はあっても良いのですが、今回は許可しない方向で考える事にしました。更新の機能はこのアプリでは必要ないので管理者も利用者も許可していません。 このルールでは「最低限」の権限を与えるという方針でルールを決めています。

これを Firebase のデータベースアクセスのセキュリティルールで書くと以下のようになります。

match /query/{query_id) {
    allow create;
    allow read, delete: if request.auth.uid == "admin_uid"
}
コレクションの名前は「query」という名前にしてみました。 「allow create」の部分が新規作成を許可している部分です。 「allow read, delete: if request.auth.uid == ....」の部分が管理者に対するルールです。管理者としてユーザー認証(ログイン)したユーザのみドキュメントの読み込みと削除ができるルールです。

管理者に関するルールは、管理者用の専用アプリを Firebase admin SDK を使って作成する場合は、セキュリティルールでアクセスの権限を設定する必要はありません。より強固なセキュリティーが必要な場合は、専用の管理アプリでデータベースの管理をする方がより安全にサイトの運営が可能です。インターネット上に管理者の権限や機能を実装しない場合は、悪意の第三者が管理者として、Firebase のデータベース(Cldoud Firestore)アクセスするのは困難になります。

ユーザー情報のコレクションの場合

では、前回紹介したような、ユーザーを管理するためのコレクションへのアクセスの場合はどうでしょうか?

実は、このアクセスの管理はもう少し複雑になります。ユーザー情報のコレクション「users」に保存するドキュメントの項目が以下のような JSON データの場合を考えてみます。

{
  "email": "E-Mailアドレス",
  "uid": "ユーザーID",
  "gid": "グループID",
  "name": "名前"
}
実際の細かい権限は、やはり開発するアプリケーションの機能によって多少変わってきます。この例では以下のような前提で Firebase のユーザー情報のコレクション・ドキュメントのアクセスルールについて考えてみます。

* 新規ユーザーの登録は「管理者」が行う
* 管理者は全ての登録ユーザーの情報を更新可能
* ユーザーの登録からの抹消(削除)は、管理者か本人のみが行える
* 一般ユーザーは自身のデータのみ更新可能(名前と E-Mail のみ変更可能)
如何ですか?前のお問い合わせフォームに比べると複雑ですね。 この例では管理者の権限の設定は除外して考えます。設定する場合でも、管理者は基本的に全ての権限を持っているので必要ならば

match /users/{user_id) {
    allow read, write: if request.auth.uid == "admin_uid"
}
を追加するだけなので、簡単ですし殆ど問題はありません。

面倒なのが一般ユーザーの Firebase のコレクション・ドキュメントのアクセス権限の設定です。設定で面倒なのは

* 自分自身のドキュメントのみのアクセス(読み込み、更新、削除)
* 他人のドキュメントのアクセスは禁止
* 更新は「email」と「name」のみ
読み込みと削除は同じ条件で良いので、ドキュメント ID と Firebase の認証によるユーザー ID(uid)が一致すれば、読み込みと削除を許可して問題がありません。

しかし、更新の場合は、「uid」と「gid」を一般利用者が勝手に変更するのは問題があるので許可するのは、「email」と「name」の変更のみです。従って、現在のデータを Firebase のデータベースから取得して、書き込むデータの「gid」と「uid」が一致している場合のみ更新(update)を許可するようなルールにします。

書き込むデータは、「request.resource.data」でセキュリティールールからアクセスする事ができます。

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));
    }
    /users/{user_id}{
        allow read,delete: if (request.auth.uid == $(user_id));
        allow update: if (request.auth.uid == $(user_id) &&
                         (request.auth.uid == request.resource.data.uid) &&
                          get_user_entry(request.auth.uid).gid == request.resource.data.gid;
    }
  }
これで、かなり細かい Firebase Cloud Firestore のドキュメントの書き込みの権限もセキュリティルールで設定できます。

まとめ
Firebase のデータベース(Cloud Firestore)の書き込みは、開発するアプリケーションによって結構複雑な権限やアクセスの制限が必要な場合が結構あります。書き込みの場合、書き込みのアクセスの分類をさらに細かく分類して、「新規作成(create)」「更新(update)」「削除(delete)」に分類して設定する事が可能です。

また、Firebase Cloud Firestore のデータをセキュリティルールから直接取得したり、書き込むデータへのアクセスもできるので、上手く組み合わせればかなり複雑なセキュリティルールの設定が可能です。

慣れないとセキュリティルールの設計だけでも結構手間がかかりますが、一旦基本的なセキュリティルールの設定の仕方をマスターすれば、バックエンドのサービスを作らなくてもかなり複雑なサービスも実現可能になります。

Firebase のデータベースの利用には、基本的にセキュリティルールの設定は必須です。まずは、基本のセキュリティルールをマスターする事が大切です。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す