0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

flutter firebase IDトークン検証で無効となる件

Last updated at Posted at 2025-11-12

概要

たいしたことではないのですが、開発中にfirebase authのGoogle SSOができない!というので数日悩んだので色々残しておきます。今回はソースコードのみ。環境準備の部分はやる気が出たら書きます
構成としてはクライアントがflutter, バックエンドにnest.jsという構成です
google_sign_in v7使用の記事です

以下のエラーがめちゃでてた

FirebaseAuthError: Firebase ID token has invalid signature. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.

まず、完成形のソースコード

Flutter側のGoogle SSOのソースコード

※以下のバージョン

firebase_core: ^4.2.0
firebase_auth: ^6.1.1
google_sign_in: ^7.2.0
login_screen.dart
import 'dart:io';

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';

  Future<void> _signIn() async {
    await _initializeGoogleSignIn();
    try {
      // 1.プラットフォームの認証機能対応の確認
      if (!_googleSignIn.supportsAuthenticate()) {
        throw Exception('Authenticate not supported on this platform');
      }

      // 2.googleサインイン
      final googleUser = await _googleSignIn.authenticate();
      final GoogleSignInAuthentication googleAuth = googleUser.authentication;
      final credential = GoogleAuthProvider.credential(
        idToken: googleAuth.idToken,
      );
      // 3.Firebase認証
      final UserCredential userCredential = await FirebaseAuth.instance
          .signInWithCredential(credential);
      // 4.このidTokenを使用
      final idToken = await userCredential.user!.getIdToken();
      
      debugPrint('firebaseIdToken: ${idToken}');
    } catch (e) {
      print('Sign-in error: $e');
      debugPrint("Error sign in google : $e");
    }
  }

  Future<void> _initializeGoogleSignIn() async {
    // Initialize and listen to authentication events
    await _googleSignIn.initialize();

    _googleSignIn.authenticationEvents.listen((event) {
      setState(() {
        debugPrint('認証後 リスナー');
        _user = switch (event) {
          GoogleSignInAuthenticationEventSignIn() => event.user,
          GoogleSignInAuthenticationEventSignOut() => null,
        };
        _email = _user?.email;
      });
    });
  }

Nest.js側のソースコード

GoogleOidc.ts
import { getAuth } from 'firebase-admin/auth';
import { Injectable } from '@nestjs/common';
import { OAuth2Client } from 'google-auth-library';

@Injectable()
export class GoogleOidc {
  constructor() { }
  public async create(idToken: string): Promise<void> {

    try {
      const decodedToken = await getAuth().verifyIdToken(idToken);

      // 2. 検証済みのPayload(ユーザー情報)を取得
      const payload = decodedToken;

      if (!payload) {
        throw new Error('IDトークンのペイロードが取得できませんでした');
      }
      // payloadを使用して後続処理を進める
    } catch (error) {
      // 検証失敗!トークンの期限切れ、改ざん、Client ID不一致など
      console.error('IDトークンの検証に失敗しました:', error);
      throw new Error('認証に失敗しました。無効なIDトークンです。');
    }
  }
}

今回のしくじり

まだ開発中で、バックエンドのAPIをたたかずコンソールに出力したIDトークンをPostmanを使って送るという形で進めているところでした
超初歩のflutterのdebugPrintが文字数制限がありIDトークンの全文が出力されていないというミスでした。。
以下の記載がミス!!

debugPrint('firebaseIdToken: ${idToken}');

以下の形でないと正しく全文でない

login_screen.dart
if (idToken != null) {
  const int chunkSize = 500; // 500文字で固定
  int i = 0;

  // トークンの長さ全体をループする
  while (i < idToken.length) {
  // 終点のインデックスを計算
  // 現在のインデックス + チャンクサイズ と トークン全体の長さの小さい方
  int endIndex = (i + chunkSize < idToken.length)
    ? (i + chunkSize)
    : idToken.length;

  // 💡 トークンを出力
  debugPrint(idToken.substring(i, endIndex));

  // 💡 次のチャンクの開始位置へ移動
  i = endIndex;
  }
}

以下を参照
https://github.com/flutter/flutter/issues/31635

google SSOの実装に当たり参考にしたサイト
https://github.com/flutter/packages/blob/main/packages/google_sign_in/google_sign_in/MIGRATION.md
https://levelup.gitconnected.com/google-sign-in-with-firebase-auth-in-flutter-e44af358f7b6

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?