首页 > 解决方案 > 在颤振上使用 FirebaseAuth.currentUser.getIdToken() 生成的 Firebase IdToken 在 Go 后端给出错误“无法验证令牌签名”

问题描述

我正在开发一个颤振应用程序,在登录后,我必须idToken使用 Firebase 管理 SDK 在自定义后端(用 Go 编写)验证用户的:firebase.google.com/go.

我正在使用以下代码段通过 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并使用带有Authentication: Bearer <token>请求标头的 Postman 将其发送到后端。

在后端,有以下内容:

  /* 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.tokenFirebaseIdToken前面方法中的不一样。)

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

任何帮助,将不胜感激!

标签: firebaseflutterfirebase-authenticationaccess-tokenfirebase-admin

解决方案


感谢 Flutter 社区的成员,我能够解决这个问题。

结果,出于某种原因,FirebaseIdToken

print("FirebaseIdToken: " + FirebaseIdToken);

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

编辑:显然,它的终端窗口通过嵌入换行符来截断/包装大输出。

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

 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 发送到后端,这次没有出错。

谢谢雷克斯福德!


推荐阅读