murave

Firestoreのセキュリティルールのこと

バックエンドをFirebaseでSPAのシステムを作る場合、データを守る砦はデータベース(今回はFirestore)のセキュリティルールです。
Authenticationのログイン情報とFirestore上のユーザー情報を紐付けし権限によりドキュメントへのアクセスを制限するなど、適切な設定しなければなりません。

service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
これは「ログインしているユーザーはフルアクセス」という最低限設定しておくべきルールです。開発中はお世話になりました。
しかし最終的にはもっとこまかく制限をかける必要がありますから、それを前提にデータ構造を設計しておいたほうが良いです。

例として今回作ったシステムのデータ構造とセキュリティルールの一部について解説します。

今回のシステムでは権限による制限が必要だったのでFirestoreにemailをキーとするコレクション、usersを作成し権限情報roleをもたせました。セキュリティルール中でAuthenticationのログイン情報からemailを取得できますので紐づけが可能です。

usersのドキュメント例(権限に関するroleのみ)

murave@hoge.var: {
role: "admin"
}
これを利用してアクセス制限を行います。一部ルールを例示します。

firestore.rules

service cloud.firestore {
match /databases/{database}/documents {
function getUser() {
return get(/databases/$(database)/documents/users/$(request.auth.token.email));
}

match /users/{email} {
allow get: if request.auth != null;
allow read, write: if getUser().data.role == 'admin';
}

match /journals/{journal} {
allow read: if getUser().data.role in ['viewer', 'admin'];
allow create: if request.auth != null;
}

match /summaries/{summary} {
allow read: if request.auth != null;
allow write: if getUser().data.role == 'admin';
}
}
}
この設定は以下の制限・意図となっています。

  • usersはログインしていればドキュメントの(個別)取得は可能。一覧取得、書き込みは管理者(admin)のみ可能。
    ログインしたユーザーが自身の権限情報を取得できる必要がある。
  • ユーザー情報は管理者が管理する。

jornalsへの新規登録はログインしていれば可能。読み出しは閲覧者(viewer)と管理者(admin)が可能。

  • これは集計前の生データなので、ログインしたユーザーすべてが入力する可能性がある。
  • 閲覧者と管理者は登録された生データの分析を行うことができる。

summariesはログインしていれば読み出しは可能。書き込みは管理者(admin)のみが可能。

  • jornalsを集計したデータでユーザーは基本的にはこの集計されたデータを見る。
  • 集計処理はjornalsへのドキュメント新規登録をトリガーとして実行されるFirebase側のFunctionで行われる。
  • 管理者は集計を修正できる。

集計処理はFirebaseのFunctionsを利用しサーバー側に委譲しており、一般・閲覧ユーザーの権限を絞ることが可能となっているのもミソです。

getUser()はAuthenticationのログイン情報のemail(request.auth.token.email)からusersのドキュメントを取得する関数です。内部で使用しているget()等、組み込みの関数には使用回数制限があることに注意してください。同じドキュメントの取得では使用回数は増えないなど独特のルールがあるので意識して、制限を超えないような構造にしなければなりません。

適切なセキュリティルールで安全なFirestoreライフを!