先日、Firebaseを利用して、Vue.js
で作ったSPA(Single Page Application)に認証機能を爆速で実装したことがあった。(ソースコードはここ)(動くアプリはここ)
Firebaseが提供する公式のJavaScript用SDKを使うことで1時間と100行以内の実装で認証機能を作ることができた。
本記事では、Firebase SDKの裏を探り、Firebase Authenticationの仕組みを理解し、実装した感想を述べる。
Firebase Authenticationのトークン認証仕組み
Firebase Authenticationはステートレスのトークン認証を採用している。ステートレスというのは今どのユーザーがログイン中なのかという状態をFirebaseバックエンド側が管理していないこと。
認証成功した後、Firebase Authenticationはトークンを発行し、それをブラウザーのIndexedDBに保存している。
IndexedDBについては、LocalStorageの上位版だと理解している。LocalStorageではKey=Value
ペアのように文字列しか保存できないのに対し、IndexedDBではJSONオブジェクトなども容易に扱える。
IndexedDBに保存されたデータを実際に見せると
stsTokenManager
の属性にaccessToken
とrefreshToken
があるのがわかる。ここのaccessToken
は内部の名前で正式の名前はFirebase ID Tokenと言われている。(https://stackoverflow.com/questions/50192454/firebase-acces-and-id-tokens)
Firebase ID TokenはFirebase Authenticationのバックエンドによって、認証プロバイダーが提供するユーザー名、パスワードなどの認証情報と控えに発行したもので、有効期間が短く、デフォルトでは一時間となっている。期限切れとなったら、Refresh Tokenを使って、新しいID Tokenを発行できる。
ID TokenはJWT(JSON Web Token)仕様である。https://jwt.io/ でトークンをデコードすると、
ペイロードにUid、ユーザー名や認証プロバイダーの情報があるのがわかる。
トークン認証についての感想
トークン認証のステートレスの性質はFirebase中のサービスまたは複数のバックエンドサービスの間にユーザー情報を共有するのに大変役立つことを実感した。
Firebaseの例を挙げると、Firestore(Firebaseが提供するNoSQLのデータストア)に特定のデータは作成者である本人しか読み取りができないというルールを実装した場合に、読み取りリクエストの送信者の身分を確認することが必要となる。
Firebase Authenticationで認証機能を実装した場合、読み取りリクエストのヘッダーにID Tokenを含めるだけで、データストア側はトークンをバリデートし、送信ユーザーを特定することができる。
また、上記と同じ感じで、Firebase Admin SDKを利用して自作サーバーなどでもログインユーザーを特定することが容易に実装できる。(詳細は公式ドキュメント)
参考