1. HOME
  2. ブログ
  3. IT技術
  4. テスト駆動で学ぶ Firestore セキュリティルール 【データ比較編 / 後編】

テスト駆動で学ぶ Firestore セキュリティルール 【データ比較編 / 後編】

テスト駆動で書籍コレクションのルールを実装する【後編】

この記事では、前編・後編の二回を通して、Firestore セキュリティルール中でのデータ比較について解説しています。

前編では、書店のネットショッピングサービスを想定した Firestore 上の書籍コレクションを例に、要件の設定からデータ追加のルールの実装までを解説しました。

後編では、「データ更新と取得のルールの実装」を進めていきます。

前回の記事はこちら

「データ比較編」の前編については、以下の記事をご覧ください。

Firestore 上のデータ更新ルールの実装

それでは、まず、データ更新用ルールの実装を進めていきます。

データ追加ルールの実装と同様、最初に、更新ルール用のテストを作成します。

データ更新の要件

テストを作成する前に、データ更新の要件を再確認しましょう!

  1. データ更新をリクエストしたユーザが商品管理者でない場合は更新不可
  2. データのサイズが「9」でない場合は更新不可
  3. タイトルが string 型でない場合は更新不可
  4. 書籍詳細が string 型でない場合は更新不可
  5. 出版日が timestamp 型でない場合は更新不可
  6. 価格が int 型で「0」以上でない場合は更新不可
  7. 在庫が int 型で「0」以上でない場合は更新不可
  8. 状態が new, used のいずれかでない場合は更新不可

ここで、一番上の商品管理者に関する要件については、データ更新の場合、「データベース上のデータの商品管理者にリクエストユーザが存在する」ことが要件となります。

テストの作成

上記の要件に沿って、テストを作成します。

tests/data.update.test.ts ファイルを追加して、以下のようにコードを記述してみましょう!

テストのコード

テストの概要

データ更新の要件は、データ追加の要件と同様の設定であるため、テストの内容も近いものとなっています。

テスト内容の主な違いは、以下の3つです。

  1. beforeEach() 内で初期データを準備していること
  2. 各テストでデータ更新メソッド update() を使用していること
  3. 「データ更新をリクエストしたユーザが商品管理者でない場合は更新不可」となるテストの内容(後述)

「データ更新をリクエストしたユーザが商品管理者でない場合は更新不可」となるテスト

データ更新については、「データベース上のデータの商品管理者にリクエストユーザが存在する」ことをアクセス許可の要件として設定しています。

商品管理者の更新を想定して、リクエストデータ中の商品管理者にリクエストユーザがいなくても、データの更新ができるように要件を設定しています。

この点は、データ追加テストの場合とは異なる点です。

リクエストユーザを含むようにデータを調整

また、リクエストデータの商品管理者に、リクエストユーザを含むようにデータを調整しています。

これにより、調整されたリクエストデータでリクエストに失敗した場合は、データベース上のデータの商品管理者に、リクエストユーザがいなかったから、「リクエストに失敗した」と判定できます。

さらに、テストの主目的である「データ更新をリクエストしたユーザが商品管理者でない場合は更新不可」となることのチェックも実施。

加えて、データベース上の商品管理者にリクエストユーザがいる場合は、リクエストデータの商品管理者にリクエストユーザがいなくても、データ更新に成功することも確認しています。

これにより、既存の商品管理者であれば、商品管理者を更新できることを担保しています。

ルールの実装

テストの開始前に、「要件にあったデータの更新に成功」するテストを通すため、以下のようにルールを調整しましょう。

テストをスタート

以下のコマンドを実行して、テストをスタートしてください!

テスト結果

データ更新の要件をセキュリティルールに設定

データ更新の要件は、データ追加の要件とほぼ同じなので、 create アクセスに対するルールを参考に、 update アクセス用のルールをまとめて追加します

create に対するルールと  update に対するルールは、ほぼ同じです。

商品管理者をチェックしている部分は異なる

ですが、商品管理者をチェックしている部分は異なります。

create アクセスのルールでは、リクエストデータの商品管理者にリクエストユーザが含まれている場合、アクセスを許可しています。

それに対して、 updateアクセスのルールでは、データベース上のデータの商品管理者にリクエストユーザが含まれている場合、アクセスを許可しています。

テスト結果

全てのテストが通ったので、書籍データ更新用のルールの実装は、これで完了です。

次のテストとの競合を避けるため、テストを終了してください。

Firestore 上のデータ取得ルールの実装

続いて、データ取得用のルールを実装していきましょう。

データ取得の要件

データの追加・更新の場合と同様、まずは、テスト作成の前にデータ取得の要件を再確認します。

  1. 下書きデータの取得不可
  2. 在庫が「5」以下の書籍の取得不可

テストの作成

上記の要件に沿って、テストを作成します。

tests/data.get.test.ts ファイルを追加して、以下のようにコードを記述します。

テストのコード

テストの概要

そして、「下書きデータの取得不可」となるテストでは、テスト前にデータベース上のデータの draft フィールドを、 true に変更して、テスト失敗用のデータを用意しています。

同様に、「在庫が「5」以下の書籍の取得不可」となるテストでは、取得対象外となる在庫数が「5」のデータを用意しています。

ルールの実装

では、テストに沿って、データ取得用のルールを実装していきます。

まずは、「要件にあったデータの取得に成功」するようにルールを調整します。

テスト結果

データ取得の要件をセキュリティルールに設定

ここまでの内容の復習となりますので、「失敗しているテスト」をまとめて通します。

resource.data.draft != true の条件により、下書きデータの取得を不可としています。

また、 resource.data.stock > 5 の条件により、在庫数が「5」以下の書籍データの取得を不可としています。

テスト結果

全てのテストが成功しましたので、書籍データの取得ルールの実装は、これで完了です。

次のテストとの競合を避けるために、テストを終了してください。

リグレッションテスト

最後に、ルールの調整を進める中で、ルールが要件から外れてしまっていないかを確認します。

全てのテストを実行

以下のコマンドを実行して、全てのテストを実行しましょう!

テスト結果

以下のような結果が表示されれば、テストは成功です!

全てのテストに成功しました!

以上で、前編冒頭で設定した「要件に沿ったルール」を実装することができました。

テスト駆動で書籍コレクションのルールを実装 データ比較後編のまとめ

以上、書店のネットショッピングサービスを例に、「Firestore 上の書籍コレクションのルールを実装」するとともに、セキュリティルール中での「データ比較」について解説してみました。

最後に、今回の内容を簡単にまとめてみたいと思います。

  1. in 演算子で値の存在チェック。マップ型ならキーの存在チェック。
  2. size() メソッドでデータの要素数チェック。文字列型なら文字数チェック。
  3. is 演算子で型チェック。
  4. 数値型は >= や < などの演算子で数値比較可。
  5. 締めのリグレッションテスト!

型や型ごとに使えるメソッドは、今回紹介したものの他にも多数用意されています。

より詳細な内容は、以下のページを参照してみてください!

【Firebase】
Namespace: rules | Firebase

こちらの記事もオススメ!

データ検証編はこちら

「データ検証編」では、リクエストデータ、データベース上のデータの参照などについて解説

データ比較編はこちら

「データ比較編」では、データの比較や型チェックなどについて解説

カスタム関数編はこちら

「カスタム関数編」では、「比較編」で作成したルールをもとに、カスタム関数の使い方を解説

書いた人はこんな人

広告メディア事業部
広告メディア事業部
「好きを仕事にするエンジニア集団」の(株)ライトコードです!

ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。

システム開発依頼・お見積もり大歓迎!

また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。

以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア