Cloud Storage for FirebaseとApp Checkを用いたファイルアップロード機能構成

# 概要
今回は無料でファイルアップロードできる仕組みをアプリ内に持たせたいと思い、FirebaseのCloud StorageとAppCheckを用いてバックエンドを構築した。
その際に自分の中でなかなか噛み砕けなかった部分を記述していきます。

# Cloud Storage for Firebase
無料枠が設けられているFirebaseが提供するBlobサーバーです。
セキュリティルールなども設けられ、Firebase Authenticationと一緒に用いることがある程度前提として作られているようです。
https://firebase.google.com/docs/storage?hl=ja
https://firebase.google.com/docs/storage/security?hl=ja

(今回は元々作成したアプリに追加する形で開発を行なったため、Firebase Authenticationは利用せずに作成しました。)
技術選定段階ではCloudflare R2も検討していたのですが、クレカ登録不要で気軽に試せるFirebaseを選択しました。
https://www.cloudflare.com/ja-jp/developer-platform/products/r2/

# AppCheck
AppCheckはFirebaseで構築したバックエンドのリソースを保護する機能を持ちます。
アプリが実際に不正なリクエストを送信された際にその通信をブロックするなど、正規の認証されているアプリからのアクセスでないと正常にアクセスさせない機能があります。
https://firebase.google.com/docs/app-check?hl=ja
今回の実装では証明書プロバイダにreCAPTCHAを用いて実装を行いました。

# 構成図
構成図としては以下のような形になります。
バックエンドリソースの上段にAppCheckがあり、そこでリクエストの確認を行い、認証されているアプリからであればリクエストを通し、その後、Cloud Storage側のセキュリティルールの要件を満たしているものであればファイルがアップロードできる形となっています。
(後述しますが個人的には実際に実装する際にこの図は理解できるのですが、AppCheckがどのようにCloud Storageと連携しているかがいまいちわからなかったです。)
![](https://storage.googleapis.com/zenn-user-upload/7daf793c6ee9-20241106.png)


# AppCheckとCloud Storageの連携
AppCheckとCloud Storageを連携するにはまず、FirebaseのConsoleよりCloud StoragenにAppCheckを適用させます。
![](https://storage.googleapis.com/zenn-user-upload/40cf17a62b1b-20241106.png)
その後、reCAPTCHA v3のコンソールよりアプリの登録を行います。
(今回がreCAPTCHA v3を利用しているだけで自身の使用した証明書プロバイダに合わせて下さい。)
基本的には以下の公式が出しているリファレンスベースで進めれば実装はできると思います。
https://firebase.google.com/docs/app-check/web/recaptcha-enterprise-provider?hl=ja

コードの詳細は割愛しますが、クライアントアプリ側にAppCheckおよび、Cloud Storageの実装を行います。
自分は以下のサイトを参考にさせていただいたのでぜひ、そちらを見てみてください。

- AppCheck
https://zenn.dev/susatthi/articles/20230316-172748-flutter-firebase-app-check
https://zenn.dev/moga/articles/appcheck_looks_good
https://qiita.com/yuta-katayama-23/items/e071e167caef2e2f780e
https://firebase.google.com/docs/app-check/web/recaptcha-enterprise-provider?hl=ja

- Cloud Storage
https://qiita.com/JSON_HardCoder/items/8d1f9b4bdd578076595d
https://firebase.google.com/docs/storage/web/start?hl=ja

結果は載せれないのですが、実際に保護が効いて、トークンがないものや登録されていないFQDNからアクセスではファイルがアップロードできないことを確認しました。

# 個人的にイメージしづらかった部分
サーバーレスとあるよにAppCheckやCloud Storage周りの動きが包括され過ぎていて個人的には処理の動きや流れがイメージしづらかったです。
ただやっていることはreCAPTCHAのフロント、バック認証を行なっているだけなのですが、理解するまではどのタイミングでクライアントのチャレンジが走り、どのタイミングでバックが走るか、また本当にCloud Storageは保護されているのだろうか？となってました。
調べたり、公式リファレンスを読んでいく中でAppCheckの適応やreCAPTCHAへの登録を行うことで裏側で上手いことやってくれるというのが徐々にわかっていきました。
個人的には各サービスにアプリを登録して適応していくことでコードベースではなく、サービス、アプリベースでバックエンド部分を構築していくイメージを作るのに時間がかかりました。。。
(以前にreCAPTCHA周りの実装を行う機会があり、コードでフロント・バックの記述、実装を行った時にイメージで行き、なかなか初めはしっくりこず。という感じでした)
上記のイメージができてからは以下の図が割とすんなり頭に入ってくるようになりました。
![](https://storage.googleapis.com/zenn-user-upload/7daf793c6ee9-20241106.png)

もし僕のようにイメージしづらいと悩んでいる方がいればまず、コードベースのことは忘れてコンソール上でアプリ登録して、、、とサービス、アプリベースで作っていくイメージを持つと良いのかもですね。

(裏側でやってることとしてはreCAPCHAなんでも以下の画像まんまだと思います。)
![](https://storage.googleapis.com/zenn-user-upload/70909b5e0215-20241106.png)

# まとめ
今回とりあえずお伝えしたいのは以下の2点です。
- AppCheckとCloud Storageを組み合わせることでセキュアーなファイルアップロード機能が簡単に作成できます。
- コードベースではなく、サービス・アプリベースでバックエンドを作っていくというイメージを持つのが良いかもです。

# おまけ
今回以下のアプリにファイルアップロード機能実装しています。
アプリの内容としては買ってよかったものを匿名で共有できるアプリです。
ぜひ、おすすめのアイテムを投稿してみて下さい！
(titleとかが設定されてない部分などは目を瞑って下さい。。。)
https://worth-it-psi.vercel.app/