前置き
こちらの続きです。
ルール変更して安全な状態を作りたい❗️
ログインユーザーかつ
送信したデータ内のuid
とauth
で取得しているuid
が
一致する場合のみ
読み書きしたい❗️
ということでやっていきます。
ルールの確認とコード修正
ルールの前提
条件を書かなければfalse
です。
この場合はcities
コレクション内の
全てのドキュメントの読み書きはできてもhogehoge
コレクションなど
別のコレクションの読み書きは
一切できません。
安心💫☝️
1 2 3 4 5 6 7 8 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /cities/{city} { allow write: if true; } } } |
前回の物をチェック
💁♀️ルールは現在こらち
1 2 3 4 5 6 7 8 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /task/{uid} { allow read, write: if request.auth != null && request.auth.uid == resource.data.uid; } } } |
前の記事の1番下、
修正コードが間違っていたので、
ルール変更前の成功コード②をそのまま使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
export const actions = { async getData({ commit }) { try { const user = this.$fire.auth.currentUser const querySnapshot = await this.$fire.firestore .collection('task') .where('uid', '==', user.uid) .get() const todos = [] querySnapshot.forEach((doc) => { const data = doc.data() todos.push(data) }) commit('setData', todos) } catch (error) { console.log(error) } }, } |
これでルール変更前の取得ができました。
しかし❗️
書き込みで権限なしのエラーが起きました💥✍️
つまり取得のルールに問題はなさそう…
しかしここには読み取りの注意はあっても
書き込みについては何も書かれていない…
データを安全にクエリする
書き込みのみtrueにしてみる
試しに変更したら、
書き込みと読み取り
両方うまく行きました。
1 2 3 4 5 6 7 8 |
service cloud.firestore { match /databases/{database}/documents { match /task/{task} { allow read: if request.auth != null && request.auth.uid == resource.data.uid; allow write: if true; } } } |
まだ送信してないのにresouce.data.uid
と
一致しないから❓
と思いましたが、
公式のサンプルコードに
書いてますからねぇ…。
ワイルドカード、再帰ワイルドカード
そしてここの下の方を見ていくと…read
とwrite
の指定場所が違う👀
データを安全にクエリする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Authenticated users can query the posts collection group // Applies to collection queries, collection group queries, and // single document retrievals match /{path=**}/posts/{post} { allow read: if request.auth != null; } match /forums/{forumid}/posts/{postid} { // Only a post's author can write to a post allow write: if request.auth != null && request.auth.uid == resource.data.author; } } } |
{path=**}
は再帰ワイルドカード、
バージョンによる注意も書いてあります。
任意の深い階層にも
適応されるというものです。
ワイルドカードと再帰ワイルドカードの違い
match/cities/{city}
citiesコレクションに一致する
全てのドキュメントに適応 /cities/SF
/cities/NYC
などなど
match/cities/{city}/{document=**}
cities
コレクション内の
全てのドキュメントの
全てのサブコレクションに適応。
この辺が参考になりそう…
と思って色々ためしたけども
ダメでした😯
つまり原因は他にある。
Firestore rules tips
CollectionGroupのFirebaseError: Missing or insufficient permissionsで躓いたときの対処法
request.resource.data
これを見て上手くいきました!!!
データの検証
書き込みの場合、
まだfirestoreにないデータを送るのでrequest
が必要ということみたいです。
なので、write
ではrequest
をつければ解決🙌💕
1 2 3 4 5 6 7 8 9 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /task/{task} { allow write: if request.auth != null && request.auth.uid == request.resource.data.uid; allow read: if request.auth != null && request.auth.uid == resource.data.uid; } } } |
成功ルールとコード
firestoreのルールと
vuex actions
のコードはこちら
1 2 3 4 5 6 7 8 9 |
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /task/{task} { allow write: if request.auth != null && request.auth.uid == request.resource.data.uid; allow read: if request.auth != null && request.auth.uid == resource.data.uid; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
export const actions = { async getData({ commit }) { try { const user = this.$fire.auth.currentUser const querySnapshot = await this.$fire.firestore .collection('task') .where('uid', '==', user.uid) .get() const todos = [] querySnapshot.forEach((doc) => { const data = doc.data() todos.push(data) }) commit('setData', todos) } catch (error) { console.log(error) } }, } |
index.vueでgetData
するようにして
実際表示するul>li
のコンポーネントでgetters
で中身を表示
1 2 3 4 5 6 7 |
<script> export default { async fetch({ store }) { await store.dispatch('getData') }, } </script> |
1 2 3 4 5 6 7 8 9 |
<script> export default { computed: { todos() { return this.$store.getters['todos'] }, }, } </script> |
まとめ
取得で.where
を使うだけでも
セキュリティを高めることはできましたが、
やはりルールを設定して
強固にしていくことも必要ですよね🌟
ルールは難しそうと感じましたが、
これらを理解しておけば
簡単なルールは設定できます✨
- firestoreへの送信データの構成
- それに合わせたワイルドカードなど
- 用意されているrequest.authなどの変数