Firebaseのルールの書き方:ユーザ毎の権限を付与&リファレンス参照

Firebase

FirebaseでFirestore・Storageへの書き込み権限を与えることで、かなり細かい制御が出来るようになります。

読み込み権限は全員にもたせたいけど、書き込み(投稿作成・削除)は作った本人だけにしたい、といった、SNS系あるあるの仕様の場合はFirestore側でちゃんとルールを作ってあげないとダメです。(javascript側の処理で出来るんじゃ…ていう考え方をする方もいらっしゃるかとは思いますが、基本的にユーザがいじることができる、クライアントサイドにこういう削除系の処理を書くとハックされる余地が残ります)

Firestoreのルールの書き方

公式にセキュリティルールのお話が書いてありますが、シンプルな構成だけなので、参考になれば。

一般的なパターン

Authenticationのuidとpostsデータのuidを比較する場合はこんな感じ。

firestore.rules

service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow read;
allow create, update, delete: if request.auth.uid == resource.data.uid;
}
}
}
}

リファレンスのデータを参照するパターン

posts自身はuidを持っておらずuserRefというuserのリファレンスのみを持っている場合はgetを挟む必要がある。リファレンス機能は感覚的にはリレーショナルデータベース的に複数のテーブルを繋げられるようにつかえるので便利に感じました。

firestore.rules

service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow read;
allow create, update, delete: if request.auth.uid == get(resource.data.userRef).data.uid;
}
}
}

storageの場合

大体firestoreと同じように書けます!

storage.rules.json

service firebase.storage {
match /b/{bucket}/o {
match /users/{userId}/posts/{allPaths=**} {
allow read;
allow create, update, delete: if request.auth.uid == userId;
}
}
}

FirestoreやStorage設定をfirebase.jsonにまとめて記載

FirebaseのGUIで登録してもいいけど、ファイルで管理してたほうが後々役に立つと思います。
特に、stagong用とproduction用の2つのFirebase環境を作ってるときとかは一回の記述で済むので便利です。

firebase.json

{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules.json"
}
}

こんな感じ。インデックス設定も一緒にファイル化できるよ。

firestore.indexes.json

{
"indexes": [
{
"collectionGroup": "posts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "userRef",
"order": "ASCENDING"
},
{
"fieldPath": "created_at",
"order": "DESCENDING"
}
]
}
],
"fieldOverrides": []
}

コメント