Chapter 06

SPAにおける認証との戦い

株式会社var(ヴァー)
株式会社var(ヴァー)
2021.09.26に更新
このチャプターの目次

こちらのチャプターでは、SPA(Single Page Application)を利用しているサービスでのセキュアな認証を構築するまでの戦いを説明します。

当初、Envaderでは、認証基盤にFirebaseを採用していました。

ユーザーのデータベースを構築する必要もなく、パスワード管理等も全てFirebaseにお願いする方針で実装を進めていました。また、フロントエンドはvue.jsでSPA化する方向で進めていました。

ここで問題が生じました。

Firebaseの認証方式はjwt(Json Web Token)だったのですが、これをどこに保存するべきかわからなくなってしまったのです。
通常、jwtはブラウザのlocal storageに保存されます。
しかし、local storageはjavascriptでアクセス可能な領域ですので、XSSの脆弱性があります。そこで、session storageに保存することを考えましたが、ブラウザのタブを閉じるごとに再ログインするのもUXとして悪くなるので却下しました。

以上より、我々はjwtをCookieに保存し、必要に応じてCSRFの対策を行うことで結論づけました。

しかしその方法で実際に構築したものの、Firebaseの持つユーザー情報は非常に限定的であり、結局は自分たちのデータベースにユーザー情報を持つ必要があると考えたため、Firebaseの利用は撤廃しました。

一見、便利そうなFirebaseですが、拡張性等を考慮すると、そうでもないという結論になりました。

最終的な構成としては、以下のようになりました。

  • 自前のデータベースでユーザー管理を行う
  • 自前の認証基盤を構築する
  • バックエンドに対する認証は、Cookieで行う

ここからは、具体的な認証の実装について解説します。
Envaderには2つの認証方式が存在しています。

  • id/pass認証
    • 弊社運営のITスクールRareTECHの生徒用アカウント
    • 企業様用アカウント
  • フェデレーション認証(Google認証)
    • 一般ユーザーアカウント

id/pass認証

こちらは、RareTECH生や企業様向けのログイン機能です。
特に難しいことはしておらず、emailとpasswordで登録します。

今回、RareTECHの生徒用ポータルサイトは、AWSで作られていたため、マルチクラウド運用となってしまいましたが、AWS側からGCPにリクエストを出すことで解決しました。

フェデレーション認証

今回は、Google認証のみを採用しました。選定理由としては、一番メジャーであり、多様なログイン方法があることはかえってUXを悪くすると考えたからです。

SPAを採用していたため、少しややこしい実装になってしましました。