Firestoreのセキュリティールールの書き方を教えてクレメンス

 コメント2件
  • 1:以下、名無しがお送りします

    Firebaseを使ってみたいんや

  • 3:以下、名無しがお送りします

    まず rules_version = '2'; って宣言するんやで

  • 8:以下、名無しがお送りします

    次に service cloud.firestore の中に match/databases/{database}/documents って書くんや

  • 14:以下、名無しがお送りします

    そこからが本番やな コレクションとドキュメントの階層に合わせて match 使って指定するんや

  • 20:以下、名無しがお送りします

    allow read, write: if true; とかやったらアカンで 誰でも読み書きできてセキュアじゃなくなるからな

  • 24:以下、名無しがお送りします

    認証済みユーザーだけ読み書きさせたいなら allow read, write: if request.auth != null; やな

  • 30:以下、名無しがお送りします

    ユーザーのuidとドキュメントID一致させるのもよくあるパターンやな

  • 40:以下、名無しがお送りします

    >>30 match /users/{userId} { allow read, write: if request.auth.uid == userId; } みたいな感じやな

  • 46:以下、名無しがお送りします

    スキーマ検証もできるで フィールドの存在チェックしたり型チェックしたりな

  • 52:以下、名無しがお送りします

    >>46 allow create: if request.resource.data.keys().hasAll(['name', 'email']) && request.resource.data.name is string; みたいな

  • 58:以下、名無しがお送りします

    バリデーションもルールでやれるで 文字数制限とか値の範囲チェックとか

  • 65:以下、名無しがお送りします

    >>58 allow update: if request.resource.data.age is int && request.resource.data.age >= 20; みたいにな

  • 73:以下、名無しがお送りします

    ネストしたデータのバリデーションはちょっと大変やけどな

  • 74:以下、名無しがお送りします

    >>73 再帰的なルール書かんとあかんねん

  • 84:以下、名無しがお送りします

    ルール関数作ってそこで存在チェックと型チェックするんがオススメやな

  • 87:以下、名無しがお送りします

    >>84 function isValidUser(user) { return user.keys().hasAll(['name', 'age', 'email']) && user.name is string && user.age is int && user.email is string } みたいな感じで

  • 97:以下、名無しがお送りします

    >>87 そしたらルールは関数使って allow create: if isValidUser(request.resource.data); でスッキリ書けるで

  • 106:以下、名無しがお送りします

    ロールベースのアクセス制御もできるんやな

  • 115:以下、名無しがお送りします

    >>106 request.auth.token.role == 'admin' みたいに Custom Claims 使うんや

  • 125:以下、名無しがお送りします

    get と list は分けて allow 書くのもポイントやな

  • 130:以下、名無しがお送りします

    >>125 allow get: if isOwner(); allow list: if isAdmin(); みたいに

  • 135:以下、名無しがお送りします

    セキュリティルールのテストはちゃんと書くんやで エミュレータ使うと捗るで

  • 142:以下、名無しがお送りします

    @firebase/rules-unit-testing 使うとテストコード書きやすいんよ

  • 147:以下、名無しがお送りします

    assertFails(db.doc('users/dummy').get()) みたいにアクセス失敗テストするんや

  • 148:以下、名無しがお送りします

    ほんで assertSucceeds(authedDb.doc('users/alice').get()) みたいに成功テストもな

  • 151:以下、名無しがお送りします

    セキュリティルールのデプロイはFirebase CLIでやるんやな

  • 158:以下、名無しがお送りします

    >>151 firebase deploy --only firestore:rules でデプロイできるで

  • 160:以下、名無しがお送りします

    >>158 デプロイはGitHubActionsとかのCIに組み込んだ方がええな

  • 167:以下、名無しがお送りします

    >>160 本番のルールを一発で書き換えるんは危険やからな

  • 168:以下、名無しがお送りします

    ステージング環境のプロジェクト作ってそこでテストするんがオススメやで

  • 171:以下、名無しがお送りします

    セキュリティルールはアプリのセキュリティに直結するから慎重にな

  • 176:以下、名無しがお送りします

    ルールの記述量が多くなってきたら ファイル分割するんもありやな

  • 180:以下、名無しがお送りします

    >>176 firestore.rules ファイルにはメインのルール書いて 共通のルール関数は別ファイルに切り出すのがおすすめ

  • 185:以下、名無しがお送りします

    >>180 例えば firestore.rules で rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } } } って感じでデフォルトを全拒否にしといて

  • 187:以下、名無しがお送りします

    >>185 各コレクションのルールは match /users/{userId} { allow read, write: if commonRule.isUserAuthenticated() && commonRule.isOwner(userId); } みたいに関数呼び出しでスッキリさせるんや

  • 194:以下、名無しがお送りします

    ルールのリファクタリングも大事やな DRYを意識してな

  • 197:以下、名無しがお送りします

    共通化できるルールはバンバン関数に切り出すんや

  • 207:以下、名無しがお送りします

    関数の命名も大事 isXxx() hasXxx() みたいな感じで

  • 211:以下、名無しがお送りします

    あとはコメント書くのも大事やな ルールは複雑になりがちやから

  • 220:以下、名無しがお送りします

    >>211 // Checks if the user is the owner of the document. function isOwner(userId) { ... } みたいにちゃんと書くんや

  • 229:以下、名無しがお送りします

    セキュリティルールはアプリの要やからな しっかり作り込むんやで

コメント(2件)

  • 1

    trueはアカンってめっちゃ大事やん

  • 2

    uid一致は基本やけどちゃんと理解せんと危ないな