Play Framework で FirebaseAuth をつかってカスタム認証フローを作る

  • 2
    いいね
  • 0
    コメント

概要

FirebaseAuth は Java 向けに SDK を公開していますが、Java の資産を活かせる言語であればこの SDK を使うことが出来ます。
この記事では、Scala 用の Play Framework でサーバを構築し自前でユーザ認証フローを作っている場合に、FirebaseAuth を組み込んでカスタム認証の対応をする手順を紹介します。

Firebase SDK の導入

build.sbtに依存を追加します。

build.sbt
libraryDependencies ++= Seq(
  "com.google.firebase" % "firebase-admin" % "4.0.3",
);

コンパイルして完了です。

$ activator compile

FirebaseApp の初期化

サービスアカウントの設定

サーバに Firebase を追加するページにある通り、サービスアカウントをコンソールで作成します。作成したら、認証情報をふくむ JSON ファイルをダウンロードし、プロジェクトのconfディレクトリ以下に配置します。

FirebaseApp の設定

GlobalSettings#onStart(Application)をオーバライドして、アプリケーションの起動時に初期化するようにします。

GlobalConfig.scala
object GlobalConfig extends GlobalSetting {
  override def onStart(app: Application): Unit = {
    super.onStart(app)
    val options = new FirebaseOptions.Builder()
        .setServiceAccount(new FileInputStream("conf/service_account_info.json"))
        .setDatabaseUrl("https://your_app_name.firebaseio.com")
        .build()
    FirebaseApp.initializeApp(options)
  }
}

カスタムトークンの取得

FirebaseAuth#createCustomToken(String)を使います。同期的な処理のフローで使う場合は、Tasks.await(Task<Result>)で包んで使います。

AuthService.scala

// REST な API の要求を受けてユーザ情報を検証・保存し、そのユーザ情報をクライアントに返すまでの処理をするクラス
class AuthService {
  def auth(): UserData = { // this method could have some args
    val user = // build a new user or fetch user data from database
    val token = // token data for this server (e.g. access token, refresh token) (not for firebase)
    val customToken = Tasks.await(FirebaseAuth.getInstance().createCustomToken(user.id))

    new UserData(user.id, user.name, token, customToken)
  }
}

カスタムトークンをクライアントに返せば、クライアントがそれを使って Firebase にサインインできるようになります。

注意点

FirebaseApp の初期化の手順は Play Framework のホットスワップと最高に相性が悪いので、コードの変更の都度アプリケーションを再起動してやる必要があります。(FirebaseApp が初期化されたかどうかのチェックをするメソッドがない。FirebaseApp#getInstance()で例外をキャッチしたら初期化みたいなことをすればよいかもしれないが…)