【Flutter】ServerpodでFirebaseAuthを使ったGoogle認証を実装する方法

プロフィール画像

柴田晃清

2025年01月27日

リンクをコピーXでシェアするfacebookでシェアする

はじめに 

Cross ApplicationOpen in new tabカンパニーの柴田です。

DartでAPIサーバを実装できるServerpodというフレームワークをご存知でしょうか?
Serverpodは、型安全なAPIコールメソッドを自動生成し、Flutterアプリとバックエンドのシームレスな通信を可能にするフレームワークです。

このServerpodを用いて社内向けアプリを開発しているのですが、その中である問題に直面しました。

Firebase Authenticationを用いたGoogle認証を実装する方法がドキュメントに書かれていない!

という問題です。
ドキュメントを見ると以下の情報は見つかります。

  • Google Cloudを用いたGoogle認証
  • Firebase Authenticationを用いた電話番号認証

しかし、Firebase Authentication + Google認証の実装方法はドキュメントには書かれていません。また、Serverpodが比較的新しい技術ということもあり私が探した限りネット上にもこの問題の解決策は見当たりません。

この記事では、試行錯誤の末に編み出した「Firebase Authentication + Google認証」の実装方法を共有・解説します。この手法は、恐らくネット上では初めて紹介されるものです。実装方法や解説が、同様の問題を抱える開発者の参考になれば幸いです!

環境

これ以外の環境では動作しない可能性があります!
詳しくは記事下部の補足をご確認ください。

# アプリ側
  firebase_core: 3.9.0
  firebase_auth: 5.3.4
  serverpod_flutter: 2.3.1
  serverpod_auth_shared_flutter: 2.3.1

# client
  serverpod_client: 2.3.1
  serverpod_auth_client: 2.3.1

# サーバ側
  serverpod: 2.3.1
  serverpod_auth_server: 2.3.1

完成形

  1. 以下のドキュメント通りsetupを実行。

  2. 以下のドキュメントの Server-side configuration と Firebase config の通りに設定を進める。Firebase Config のステップ4では、firebase_auth を追加する。


  3. Google認証ボタンを実装する。
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            // ①
            GoogleAuthProvider googleProvider = GoogleAuthProvider();
            final UserCredential credential =
                await FirebaseAuth.instance.signInWithPopup(googleProvider);
            final idToken = await credential.user?.getIdToken();

            // ②
            final serverResponse =
                await client.modules.auth.firebase.authenticate(idToken!);
            if (!serverResponse.success) {
              throw Exception('Failed to authenticate with server');
            }

            // ③
            await sessionManager.registerSignedInUser(
              serverResponse.userInfo!,
              serverResponse.keyId!,
              serverResponse.key!,
            );
          },
          child: Text('Sign in with Google'),
        ),
      ),
    );
  }

解説

            // ①
            GoogleAuthProvider googleProvider = GoogleAuthProvider();

            final UserCredential credential =

                await FirebaseAuth.instance.signInWithPopup(googleProvider);

            final idToken = await credential.user?.getIdToken();

① Firebase Authenticationを使ってGoogle認証を行い、②で必要なOIDCの ID Token を取得しています。以下のFirebaseのドキュメントを参考にID Tokenを取得しています。

            // ②
            final serverResponse =

                await client.modules.auth.firebase.authenticate(idToken!);

            if (!serverResponse.success) {

              throw Exception('Failed to authenticate with server');

            }

② ID Tokenを用いてServerpodの認証エンドポイントをコールして、ID Tokenの検証・認証しています。Tokenを渡している client.modules.auth.firebase.authenticate は serverpod_auth_serverパッケージにて生成されたエンドポイントです。


Firebase Authenticationで電話番号認証を実装する手順が書かれているドキュメントに載っている signInWithFirebase() の実装を読み進めていたところ発掘しました。

            // ③
            await sessionManager.registerSignedInUser(

              serverResponse.userInfo!,

              serverResponse.keyId!,

              serverResponse.key!,

            );

③ アプリ側のsessionManagerに認証情報を登録しています。これにより、以降のServerpodのAPIを呼び出す際は認証済みユーザとして実行されます。

補足

⚫︎ Serverpodの認証機能に変更が入りこの記事の方法は推奨されない、または、実行できなくなる可能性があります。2025年1月時点では、破壊的変更は加えず徐々に新しい書き方に移行を促すロードマップになっているようです。筆者の推測ではありますが、少なくとも2.X系の間は今回紹介した方法が有効ではないかと予測しています。最新情報はこちらをご確認ください。

⚫︎ 認証済みユーザーのみAPIアクセスを許可する方法はこちらを参照してください。

⚫︎ serverpod_auth_firebase_flutterパッケージ, firebase_ui_authパッケージ, firebase_ui_oauth_googleパッケージを駆使することでも実装できそうだったのですが、柔軟性にかけるため現在の実装にしています。

まとめ

Serverpodにおける Firebase Authentication + Google認証の実装の一例を紹介してきました。補足にも書きましたが、他の方法でも実装可能だと思います。プロジェクトの特性に合わせて検討いただければと思います!

この記事を書いた人

柴田晃清
柴田晃清
2021年メンバーズに入社。現在Cross Applicationカンパニーに所属。FlutterとAWSが好き。
ページトップへ戻る