在 flutter 上使用 FirebaseAuth.currentUser.getIdToken() 生成的 Firebase IdToken 在 Go 后端给出错误 "failed to verify token signature"

Firebase IdToken generated using FirebaseAuth.currentUser.getIdToken() on flutter gives error "failed to verify token signature" on Go backend

我正在开发一个 flutter 应用程序,在 sign-in 之后,我必须使用 Firebase admin SDK 在自定义后端(用 Go 编写)验证用户的 idTokenfirebase.google.com/go.

我正在使用以下代码段 sign-in 通过 GoogleSignIn 的用户并在客户端检索 Firebase idToken:

final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();

Future<String> signInWithGoogle() async {
  await Firebase.initializeApp();
 
  final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
  
  final GoogleSignInAuthentication googleSignInAuthentication =
      await googleSignInAccount.authentication;

  final AuthCredential credential = GoogleAuthProvider.credential(
    accessToken: googleSignInAuthentication.accessToken,
    idToken: googleSignInAuthentication.idToken,
  );  

  final UserCredential authResult = await _auth.signInWithCredential(credential);

  final User user = authResult.user;

  String FirebaseIdToken = await _auth.currentUser.getIdToken();
  print("FirebaseIdToken: " + FirebaseIdToken);
  
  if (user != null) {
    /* code to validate user and return it */
  }  return null;
}

我复制对应于 FirebaseIdToken 变量的令牌,并使用 Postman 将其发送到后端,并使用 Authentication: Bearer <token> 请求 header.

在后端,有以下内容:

  /* am.cli here is basically the auth.Client in firebase admin SDK and clientToken is the token received from flutter app. */
  idToken, err := am.cli.VerifyIDToken(context.Background(), clientToken) 
  log.Println("ERROR:", err)

我打印出以下错误:

  ERROR: failed to verify token signature

根据客户端和后端的文档,我相信我正在使用正确的方法来检索和验证令牌。

我也尝试使用以下代码检索 idToken:

  IdTokenResult idTokRes = await _auth.currentUser.getIdTokenResult(true);
  print("idTokRes: " + idTokRes.token);

但这同样失败了。 (而且 idTokRes.token 和之前方法的 FirebaseIdToken 不一样。)

我还尝试在 https://jwt.io/ 上使用 public 证书和私钥手动验证令牌,但也失败了。

如有任何帮助,我们将不胜感激!

感谢 Flutter 社区的一位成员,我得以解决问题。

原来,由于某种原因,

打印的 FirebaseIdToken
print("FirebaseIdToken: " + FirebaseIdToken);

不是完整的令牌。由于很大,输出会被截断。 (虽然仍然不确定为什么。Dart 的 print() 语句会截断大字符串吗?

编辑:显然,它的终端 window 是 truncates/wraps 通过嵌入换行符的大输出。

但是,通过使用以下代码段

 String firebaseIdToken = await user.getIdToken();
 while (firebaseIdToken.length > 0) {
   int startTokenLength =
       (firebaseIdToken.length >= 500 ? 500 : firebaseIdToken.length);
   print("TokenPart: " + firebaseIdToken.substring(0, startTokenLength));
   int lastTokenLength = firebaseIdToken.length;
   firebaseIdToken =
       firebaseIdToken.substring(startTokenLength, lastTokenLength);
 }

我能够在 3 个损坏的部分中打印完整的令牌,然后将它们连接起来,并通过 Postman 发送到后端,这次没有出错。

谢谢雷克斯福德!