1. HOME
  2. ブログ
  3. IT技術
  4. テスト駆動で学ぶ Firestore セキュリティルール 【データ検証編 / 後編】
test-dirven-firestore-security-rules-data-verification-2nd

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

テスト駆動で商品データのルールを実装する【後編】

この記事では、前編・後編の二回に分けて、Firestore 上の商品データコレクションのセキュリティルール実装を例に、ルールによるデータ検証について解説しています。

前編では、「実装目標の設定」から「データ追加ルールの実装」までを解説しました。

後編では、「データ更新・取得ルールのテスト駆動による実装」を進めつつ、「データベースにすでにあるデータの利用」などについて解説していきます。

簡単な流れ

以下のような流れで解説を進めていきます。

  1. Firestore 上のデータ更新ルールを実装・解説
  2. Firestore 上のデータ取得ルールを実装・解説
  3. 全体テストで要件の最終チェック
  4. まとめ

前編の記事はこちら

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

テストの作成

前編で説明した、データ追加ルールの実装と同様、テスト駆動で「商品データ更新ルール」の実装を進めていきます。

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

  1. データ更新をリクエストしたユーザが商品管理者と一致しない場合は追加不可
  2. 商品管理者の変更不可
  3. ロックされたデータの更新不可
  4. 商品名の変更不可

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

tests/data.update.test.ts ファイルを追加して、以下のようにコードを記述してください。

テストのコード

テストの概要

初期データの準備

beforeEach(...) 内で、初期データの準備を行っています

「商品管理者の変更不可」テスト

const bad_data = {...validUpdateData, admin_user: other_user}; の部分で、更新データに元の商品管理者とは異なるユーザを設定しています。

「ロックされたデータの更新不可」テスト

以下の部分で、更新失敗をチェックする前に、ロックされたデータを用意しています。

Firestore セキュリティルールの実装

商品データ更新用のテストが完成したので、ルールの実装を進めていきます。

テストをスタート

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

テスト結果

以下のような、テスト結果が表示されます。

商品データ追加をテストしたときと同じく、上から順にテストを通していきます

全ての update アクセスを許可するセキュリティルールを設定

「要件にあったデータの更新に成功」テストを通すため、とりあえず全ての update アクセスを許可してみます。

以下のように Firestore セキュリティルールを調整してください。

テスト結果

以下のような、テスト結果が表示されます。

「要件にあったデータの更新に成功」テストが成功しました。

ユーザ情報を許可条件に使用するセキュリティルールを設定

次は、「データ更新をリクエストしたユーザが商品管理者と一致しない場合は追加不可」テストを通したいと思います。

商品データ追加の要件と同じく、 create に対するルールにならって、以下のようにルールを調整します。

テスト結果

テスト結果は、こんな感じになりました。

データベース情報を許可条件に使用するセキュリティルールを設定

次に、「商品管理者の変更不可」テストを通すため、以下のようにルールを調整してください。

resource.data フィールドを使って、データベースに保存されているデータを参照することができます。

request.resource.data.admin_user == resource.data.admin_user の条件では、リクエストデータと既存データの admin_user が一致していることをチェックし、商品管理者に変更がないことを確認しています。

テスト結果

テスト結果は、以下の通りとなります。

「商品管理者の変更不可」テストが通りました。

残りの要件をセキュリティルールに設定

次に、残りのテストを通すため、以下のように Firestore セキュリティルールを調整してください。

「商品管理者の変更不可」の場合と同様、 request.resource.data.title == resource.data.title の条件により「商品名の変更不可」としています。

また、 resource.data.locked == false の条件により、「ロックされたデータの更新不可」としています。

テスト結果

テスト結果は、以下の通りとなります。

テストが全て通りましたので、以上で商品データ更新用のセキュリティルールの実装は完了です。

次のテストとの競合を避けるために、商品データ更新用のテストを終了してください。

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

テストの作成

最後に、商品データ取得用の Firestore セキュリティルールをテスト駆動で実装していきます。

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

  1. 認証されていないユーザはデータ取得不可
  2. 売り切れ商品のデータ取得不可

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

tests/data.read.test.ts ファイルを追加し、以下のようにコードを記述してください。

テストのコード

テストの概要

「要件にあったデータの取得に成功」テスト

任意の認証されたユーザがデータを取得できるので、任意ユーザ any_user で認証されたクライアントを使用しています。

「売り切れ商品のデータ取得不可」テスト

以下のコードで、売り切れ商品のデータを用意しています。

Firestore セキュリティルールの実装

テストに沿って、Firestore セキュリティルールの実装を進めていきます。

テストをスタート

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

全ての read アクセスを許可するセキュリティルールを設定

商品データの追加・更新テストの場合と同様、この時点では、「要件にあったデータの取得に成功」テストは「失敗」します

まずは、これまでと同様、全ての read アクセスを許可してみます。

以下のようにルールを調整してください。

テスト結果

テスト結果は、以下の通りとなります。

「要件にあったデータの取得に成功」したので、残りの取得不可ルールを追加していきます。

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

以下のように Firestore セキュリティルールを調整してください。

ここで、 request.auth.uid != null により、認証されているユーザだけがデータ取得可能としています。

また、 resource.data.sold_out == false の条件により、売り切れていない商品のみ取得可能としています。

テスト結果

テスト結果は、以下の通りとなります。

テストが全て成功したので、以上で商品データ取得用のセキュリティルールの実装は完了です。

テストを終了してください。

全ての要件の再チェック

最後に、各項目でのルールの変更により、前に設定したルールが要件から外れていないかを確認します。

全てのテストを実行

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

テスト結果

テスト結果は、このような感じになりました!

全てのテストに成功したので、これで前編冒頭に設定した、要件に沿ったルールの実装が完了しました。

Firestore セキュリティルールによるデータ検証のまとめ

以上、Firestore セキュリティルールでのデータの検証を、テスト駆動で解説してみました。

この記事では、解説のわかりやすさのため、個別のテストファイルについてテストを実施してきました。

ですが、実際の開発では、最初から全テストを実行することをおすすめします

なぜなら、実装と並行して常にリグレッションテストが実行されるからです。

既存のテストの失敗に早目に気づくことができ、原因の特定・修正も比較的簡単で済みます。

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

  1. request.auth フィールドィールドでリクエストユーザの情報を参照できる
  2. request.resource.data フィールドでリクエストデータを参照できる
  3. resource.data で既存データを参照できる
  4. 更新不可ルールは request.resource.data.some_data == resource.data.some_data で実装
  5. request.auth.uid != null で認証なしユーザをブロック

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

データ検証編はこちら

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

データ比較編はこちら

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

カスタム関数編はこちら

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

書いた人はこんな人

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

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

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

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

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

関連記事

採用情報

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

バックエンドエンジニア

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

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

\ 世界を変える…! /

Androidエンジニア

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

iOSエンジニア