Slide 1

Slide 1 text

ここまで出来るよ Firestore セキュリティルール @Ryo Kawamata

Slide 2

Slide 2 text

0. 自己紹介

Slide 3

Slide 3 text

@RyoKawamata 消防士歴 6年半 エンジニア歴 1年半 Ruby / Typescript Firebase / Vue.js

Slide 4

Slide 4 text

1. Firestoreって何?

Slide 5

Slide 5 text

Firebaseが提供する スケーラブルなNoSQL のデータベース

Slide 6

Slide 6 text

Firestoreの特徴

Slide 7

Slide 7 text

ドキュメント指向のNoSQL

Slide 8

Slide 8 text

Data Document Collection

Slide 9

Slide 9 text

Collection Data Document

Slide 10

Slide 10 text

リアルタイム同期

Slide 11

Slide 11 text

websocket不要でデータの更新が リアルタイム同期される

Slide 12

Slide 12 text

NoSQLなのに アトミックオペレーション が使える

Slide 13

Slide 13 text

トランザクション 一括書き込み 一つ以上のドキュメントに対して対 して書き込みを行う一連のオペ レーション。読み込みでのロックを 行わないため、実行速度が早い。 一つ以上のドキュメントに対して読 み書きを行う一連のオペレーショ ン。読み込みのロックのため、整合 性は高いが、実行速度は遅い。

Slide 14

Slide 14 text

フロントエンドの 開発スピードアップ

Slide 15

Slide 15 text

通常の Webアプリ Front end Back end DB ORM REST API Firestore利用 Front end Fire Store Client SDK

Slide 16

Slide 16 text

使いやすいSDK

Slide 17

Slide 17 text

ドキュメントの追 加 ドキュメントの取 得 firestore().collection("users").add({ name: "太郎", sales: 10000 }); firestore().collection("users") .where("sales", ">", 5000) .orderBy("sales", "desc");

Slide 18

Slide 18 text

高いSLOとスケーラビリティ

Slide 19

Slide 19 text

Resional 99.99 % Multi-Resion 99.999 % SLO Designed to scale We've designed Cloud Firestore to handle the toughest database workloads from the world's biggest apps. 世界最大のアプリからの最も厳しいデータベース ワークロードを処理するように設計.

Slide 20

Slide 20 text

良心的な料金体系

Slide 21

Slide 21 text

Sparkプラン (無料) Flameプラン ($25/月) Blazeプラン (従量課金) 保存データ 合計 1GiB 合計 2.5GiB $0.18 / GiB 帯域幅 10GiB / 月 20GiB / 月 Google Cloud pricing ドキュメントの 書き込み 2万 / 日 10万 / 日 $0.18 / 10万 ドキュメントの 読み取り 5万 / 日 25万 / 日 $0.06 / 10万 ドキュメントの 削除 2万 / 日 10万 / 日 $0.02 / 10万 2019/10/8 時点

Slide 22

Slide 22 text

もはや最高..!!!!!

Slide 23

Slide 23 text

でも..

Slide 24

Slide 24 text

clientから処理されるって、 セキュリティ大丈夫... スキーマレスって変なデータ入って バグになりやすそう.. Validationがフロントだけだと、 怖いような..

Slide 25

Slide 25 text

大丈夫!!!

Slide 26

Slide 26 text

セキュリティルール がある!!

Slide 27

Slide 27 text

3. セキュリティルールとは?

Slide 28

Slide 28 text

Firestoreが提供する サーバーサイドでアクセス制御、 データ検証が出来る機能

Slide 29

Slide 29 text

service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read: if true; allow write: if false; } } } ex) usersコレクションを読み取り専用にするルール 対象のコレクション 条件 許可する操作

Slide 30

Slide 30 text

4. セキュリティルール で出来ること

Slide 31

Slide 31 text

ユーザー認証

Slide 32

Slide 32 text

Firebase Authentication 認証済みのユーザーで、かつ 自分のドキュメントしか閲覧できない RULE

Slide 33

Slide 33 text

function isAuthUser(auth, userId) { return auth != null && auth.uid == userId } match /databases/{database}/documents { match /users/{userId} { allow read: if isAuthUser(request.auth, userId); } } request.auth で認証情報を取得

Slide 34

Slide 34 text

スキーマ検証

Slide 35

Slide 35 text

ドキュメントは以下スキーマを持つ RULE カラム名 型 name String sales Number

Slide 36

Slide 36 text

function isValidSchema(data) { return data.size() == 2 && 'name' in data && data.name is string && 'sales' in data && data.sales is number } match /databases/{database}/documents { match /users/{userId} { allow create: if isValidSchema(request.resources.data); } } request.resources.data で送信データを取得

Slide 37

Slide 37 text

バリデーション

Slide 38

Slide 38 text

ドキュメントは以下条件を持つ RULE カラム名 条件 name 30文字以内 gender male, female, genderDivers のいずれかの値を持つ

Slide 39

Slide 39 text

function isValidData(data) { return 'name' in data && 1 <= data.name.size() && data.name.size() <= 30 && 'gender' in data && data.gender.matches('male|female|genderDiverse') } match /databases/{database}/documents { match /users/{userId} { allow create: if isValidData(request.resources.data); } } 関数 で送信データを判定

Slide 40

Slide 40 text

関連でのバリデーション

Slide 41

Slide 41 text

messagesはusersドキュメントの ageが18以上の場合に追加できる RULE

Slide 42

Slide 42 text

function isValidData(data) { return get(/databases/$(database)/documents/users/$(data.userRef)) .data.age >= 18 } match /databases/{database}/documents { match /messages/{message} { allow create: if isValidData(request.resources.data); } } get() で別ドキュメントのデータを参照

Slide 43

Slide 43 text

Firebase Authとの連携

Slide 44

Slide 44 text

admin 権限を持つユーザーのみ 投稿を許可する RULE

Slide 45

Slide 45 text

function isAdminUser(auth) { return auth.token.admin == true; } match /databases/{database}/documents { match /users/{userId} { allow create: if isAdminUser(request.auth); } } custom claimsでadminを判定

Slide 46

Slide 46 text

パラメータの変化で判定

Slide 47

Slide 47 text

statusは`order`から`shipment` の順で変化する RULE

Slide 48

Slide 48 text

function isValidUpdate(oldData, newData) { return oldData.status.matches('order') && newData.status.matches('shipment') } match /databases/{database}/documents { match /users/{userId} { allow update: if isValidUpdate(resource.data, request.resources.data); } } resource.data で 変更前のデータを取得して判定

Slide 49

Slide 49 text

4. 注意すべきところ

Slide 50

Slide 50 text

get関数は金額計算対象

Slide 51

Slide 51 text

Admin SDKでは セキュリティルールは効かない

Slide 52

Slide 52 text

5. まとめ

Slide 53

Slide 53 text

Firestoreは最高のデータベース。 ただそれを実現するためには、 セキュリティルールを しっかり書くことが大切 !! セキュリティルールを書いて より良いFirestore ライフを送ろう!!