iimonで主にフロントエンドを担当している澤岻(たくし)です。
最近開発を進めているプロダクトでFirebaseを利用していてテストを書き始めたのですが、
テストについて記事を書こう!
と思ったところ、そもそものデータ構造やセキュリティルールなどについてはまだ書いてなかったのでまずはそこをまとめておくことにしました。
Firestoreってどんなもの?
Firebaseダッシュボード
FirebaseとはGoogleが提供する開発プラットフォームで、認証やデータベースだけではなく、さまざまなサービスを提供しています。
Firebaseが提供するサービスの一つであるFirestoreは、NoSQLドキュメント型データベースサービスの1つです。
クラウドサービスなので、比較的簡単かつスピーディーにデータベースを利用することができますし、Firebaseが提供する認証サービス(Firebase Authentication)と連携することもできます。
Firestore用語(ざっくりver.)
初めてFirestoreを使う場合、見慣れぬワードがちらほら出てきます。
(というかそもそもNoSQLとか自体あんまわからん!ってなる場合は以下の記事などオヌヌメです。)
https://aws.amazon.com/jp/nosql/
https://zenn.dev/nameless_sn/articles/nosql-manual
主に基本として押さえておきたいのが以下の二つです。
Document (ドキュメント)
ストレージの単位で、値にマッピングされるフィールドを含む軽量のレコード。
例えば、Japanを表すドキュメントは以下のようになります。
Japan(ドキュメント)
currency: 'yen' language: 'Japanese' primeMinister: { firstName: 'Fumio' lastName: 'Kishida' }
ブール値、数値、文字列、地理位置情報、バイナリ blob、タイムスタンプ
などさまざまなデータ型がサポートされています。
Collection (コレクション)
ドキュメントを格納するコンテナ。
ドキュメントがレコードでコレクションがテーブルという感覚ですね!
上記の例の場合だと、以下のようなコレクションになりそうです。
countries(コレクション)
Japan currency: 'yen' language: 'Japanese' primeMinister: { firstName: 'Fumio' lastName: 'Kishida' }
実際のfirestoreのパネルビュー
セキュリティルール
Firebaseのデータベースサービス(Firestore、Realtime database)を利用するにあたり、なくてはならないのがこの「セキュリティルール」という機能です。
セキュリティルールはデータベースに対してユーザーの読み書きの制限をするもので、認証状態やユーザー情報をもとに細かく制限をかけることができます。
逆に言えば、セキュリティルールをしっかり設定しておかなければ、
データベース上の特定のユーザー情報などが他のユーザーにもアクセス可能になってしまいます。
セキュリティルールは、セキュリティルール言語という独自言語に基づいていますが、記述できる式はJavaScriptに非常に似たものなので比較的とっつきやすいかと思います。
セキュリティルール自体は、Firebase console (管理画面) > Firestore内にあるルールページで直接編集できるようになっています。
実際のルール設定画面(初期状態)
ルール例をご紹介
まずは特に読み書き制限をしない場合です。
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if true } } }
主にルール設定に関する箇所だけ抜粋すると、
match /databases/{database}/documents {
この宣言では、作成されたデータベース対象としたルールであるということを示します。
match /databases/{database}/documents { ... match /{document=**} {
そして{}内にネストされる形で宣言されていますが、{document=**}
では、全てのドキュメントを対象としたルールである
ということを示します。
match /databases/{database}/documents { ... match /{document=**} { allow read, write: if true
そしてこれがルール式を含めた状態です。
この場合だと常にif文がtrueを返すのでreadもwriteも誰でも可能ということになります。
これではセキュアとはいえません。
Firebaseで認証済みのユーザーのみに制限したルール
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if request.auth != null } } }
FirestoreではFirebase Authenticationと連携することができます。
request.authは、リクエストしたユーザーの認証情報であり、ログイン済みであることを示します。
Firebase Authenticationでログイン済みのユーザーからのアクセス時のみ、read writeを許容するということになります。
ドキュメントごとに個別のルールを設定する
users, companiesというコレクションが存在するという想定で、ドキュメントごとに別のルールを設定します。
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, update, delete: if request.auth != null && request.auth.uid == userId; allow create: if request.auth != null; } match /companies/{company} { allow read, write: if request.auth != null } } }
usersコレクションでは、
ユーザーがログイン済みである、かつアクセスするユーザー本人のみドキュメントに対してread, update, deleteが可能であり、
ログイン済みであればcreateが許可される。
ということになります。
対してcompaniesコレクションに関しては、ログイン済みであれば読み書きが可能ということになります。
また他にもデータ要求があるドキュメントのデータを参照してその値を元に制限をかけたり、
他のドキュメントの情報にアクセスしたりもできます。
https://firebase.google.com/docs/firestore/security/rules-conditions?hl=ja&authuser=0
セキュリティルールは比較的柔軟に設定することができますし、
ドキュメントごとに適切なルールを個別に設定することがセキュリティを担保する上では大切そうです。
まとめ
セキュリティルールはFirestoreを使ってデータ管理をする上では重要ですし、
設定したセキュリティルールの見直しなどは定期的に行うべきですね。
また、冒頭でも軽く触れましたが、Firebase emulatorを使用すれば、ルールのテストも可能なので、そこについても実装後にまとめておきたいと思います!
参考資料
https://firebase.google.com/docs/firestore?hl=ja&authuser=0
https://firebase.google.com/docs/firestore/security/rules-structure?hl=ja&authuser=0
https://aws.amazon.com/jp/nosql/
https://zenn.dev/nameless_sn/articles/nosql-manual
https://firebase.google.com/docs/firestore/security/rules-conditions?hl=ja&authuser=0