问题描述
我正在开发一个 Flutter 应用,登录后,我必须使用 Firebase 管理 SDK 在自定义后端(用 Go 编写)验证用户的 idToken
: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
变量对应的令牌,并使用 Postman 和 Authentication: Bearer <token>
请求标头将其发送到后端。
在后端,有以下内容:
/* 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/ 上手动验证令牌,但也失败了。
任何帮助将不胜感激!
解决方法
感谢 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 发送到后端,这次没有出现错误。
感谢雷克斯福德!