👏

フロントエンド(SPA)でのFirebase Authとの付き合い方

2020/11/03に公開

Firebase Authで取得したID Tokenをどう使うか、どう保管するかが結構難しいと思っています。
その中で、WebアプリケーションにおいてFirebaseのドキュメントには2パターンがあるように見えました。

  1. Cookieを使ったSession管理
  2. ID Token+Service Workerを使った管理(Betaっぽい)

自分としてはそれぞれのメリット・デメリットがあると感じましたので、まとめます。

1. Cookieを使ったSession管理

  • メリット
    • 自分でCookieの長さを決められる.2週間に設定することもできる(ID Tokenの期限は1時間)
    • 古いブラウザでもサポートしている方法
    • Cookieの保存自体はブラウザがやってくれる、リクエスト時に何かを見る必要がない
  • デメリット
    • サーバ側の受け取り口でCookieがあるかを見る必要がある(iOSやAndroidアプリを作る場合にその部分の修正が入る)

細かいソースコードなどの例は以下になります
https://firebase.google.com/docs/auth/admin/manage-cookies?hl=ja

シーケンス図としては以下のようになります

2. ID Token+Service Workerを使った管理

  • メリット
    • サーバの検証部分がシンプルになる(iOSやAndroidアプリと同じようにHeaderの検証をする
    • リクエスト時にfetchが動くのでリクエストの際に何かを見る必要が必要がない
  • デメリット
    • 古いブラウザではService Workerがサポートされてなかったり、まだService Worker自体草案である

細かいソースコードなどの例は以下になります
https://firebase.google.com/docs/auth/web/service-worker-sessions?hl=ja

サンプルとして以下のようになります
https://github.com/FirebaseExtended/firebase-auth-service-worker-sessions

シーケンス図としては以下のようになります

fetchはSPAのAPIリクエストでも動くため、外部APIに対する認証の場合でも問題はありません。
例えば、対象のドメインでのリクエストの場合にID Tokenをつけるようにして、そのserverでID Tokenの検証をします。

SPAでの管理について

では、実際の流れで考えてみます。以下で使うサービスはすべてLoginが必要なものと考えます(面倒なのでTopPageでも、ログインが必要とします)

1. サービスの初回アクセス

このとき、1と2のときは挙動は変わりません。Loginページへ遷移させるが正しいと思います。

2. ログインした後、1日後などで再度サービスにアクセスしてきたとき

1ではCookieにデータがありますので、サーバにリクエストが来た時点でLogin判定ができます。そのため、Loginページを表示する必要はありません。

2ではService Workerがブラウザで判定するためにも、一度ページを表示しなければ、Login判定ができません。そのため一度Loginページを表示する必要が出てくるかもしれません(これはページの仕様によります)
*これは現状検証中です、もし違うっていうのであれば教えてほしいです

3. リクエスト時に認証切れだったとき

1と2のときでサーバにリクエストが来た時点、検証します。その際に省かれます。
あえて言えば、1の場合はCookieの期限が切れたときは、サーバからのレスポンスで判定します。
しかし、2のときはclientでupdateを繰り返し、また、client側で、未ログインかどうかを判定できますので、この問題にぶつかる可能性は低くなります

4. ログインしているかどうかの判断

1ではresponseのCookieがあるかどうかで、判断しても良いかもしれません。(httpOnlyであり、domain設定をしているとより良いです)
2ではService Workerの中からブラウザへ通知をしてそれを元に判定するのが良いかと思います。

まとめ

一長一短あると思いますが、Cookieの使い方が見直されている中、今後はID Token+service workerのような認証は多くなりそうだと感じております。
ただ、現状はまだ使うにはちょっと早いかなという印象です。

Discussion