I need to do google signin in flutter app using firebase. Generate idToken at client, and send it to backend Admin SDK for verification of idToken.
Issue: I am getting below error when calling method of Firebase Admin SDK.
FirebaseAuth.getInstance(firebaseApp).verifyIdToken(clientIdToken);
error:
com.google.firebase.auth.FirebaseAuthException: Failed to parse Firebase ID token. Make sure you passed a string that represents a complete and valid JWT. See https://firebase.google.com/docs/auth/admin/verify-id-tokens for details on how to retrieve an ID token.
at com.google.firebase.auth.FirebaseTokenVerifierImpl.newException(FirebaseTokenVerifierImpl.java:237)
at com.google.firebase.auth.FirebaseTokenVerifierImpl.parse(FirebaseTokenVerifierImpl.java:153)
at com.google.firebase.auth.FirebaseTokenVerifierImpl.verifyToken(FirebaseTokenVerifierImpl.java:99)
at com.google.firebase.auth.AbstractFirebaseAuth$3.execute(AbstractFirebaseAuth.java:307)
at com.google.firebase.auth.AbstractFirebaseAuth$3.execute(AbstractFirebaseAuth.java:304)
at com.google.firebase.internal.CallableOperation.call(CallableOperation.java:36)
at com.google.firebase.auth.AbstractFirebaseAuth.verifyIdToken(AbstractFirebaseAuth.java:269)
at com.google.firebase.auth.AbstractFirebaseAuth.verifyIdToken(AbstractFirebaseAuth.java:241)
at com.dummy.poc.firebase.FirebaseApplicationTests.contextLoads(FirebaseApplicationTests.java:45)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.IllegalArgumentException: com.google.common.io.BaseEncoding$DecodingException: Invalid input length 153
at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:218)
at com.google.api.client.util.Base64.decodeBase64(Base64.java:106)
at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:551)
at com.google.api.client.auth.openidconnect.IdToken.parse(IdToken.java:155)
at com.google.firebase.auth.FirebaseTokenVerifierImpl.parse(FirebaseTokenVerifierImpl.java:143)
... 76 more
Caused by: com.google.common.io.BaseEncoding$DecodingException: Invalid input length 153
at com.google.common.io.BaseEncoding$Base64Encoding.decodeTo(BaseEncoding.java:968)
at com.google.common.io.BaseEncoding.decodeChecked(BaseEncoding.java:233)
at com.google.common.io.BaseEncoding.decode(BaseEncoding.java:216)
... 80 more
Client code:
pubsec.yml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
provider: ^6.0.0
google_sign_in: ^5.0.7
firebase_core: ^1.6.0
firebase_auth: ^3.1.1
ControllerLogin.dart
allowUserLoginWithGoogle() async{
UserCredential credential = await signInWithGoogle();
print('in allowUserLoginWithGoogle after google sign in');
User? user = credential.user;
String? idToken = await user?.getIdToken(); // I have tried for this idToken verification also. getting same error but instead of 153 getting 157
User? mUser = await FirebaseAuth.instance.currentUser;
var mUserIdToken = await mUser?.getIdToken(); // I am sending this IdToken to backend for verification and getting error on verifying the same.
notifyListeners();
}
Future<UserCredential> signInWithGoogle() async {
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
final GoogleSignInAuthentication? googleAuth = await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
await Firebase.initializeApp();
return await FirebaseAuth.instance.signInWithCredential(credential);
}
Backend verify id token code
public FirebaseApp firebaseApp() throws Exception {
FileInputStream serviceAccount =
new FileInputStream("/Users/anonymous/Documents/app/poc/firebase/src/main/java/com/dummy/poc/firebase/auth-test-project-b0c91-firebase-adminsdk-vrz4u-ab7b3962b0.json");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.build();
return FirebaseApp.initializeApp(options);
}
@Test
void contextLoads() throws Exception {
String mUserIdToken = <id token from client>;
FirebaseToken firebaseToken
FirebaseAuth.getInstance(firebaseApp()).verifyIdToken(mUserIdToken); // this line is giving me above error
}
I have tried verifying the idToken on jwt.io. There I am able to decode the jwt token although it shows invalid signature but the token is getting decoded on jwt.io
Please help.
2
Answers
It's absolutely my mistake. I was not knowing the difference between access token and idToken and also diff between Oauth2 and OIDC. later after reading about these concepts, I am able to resolve it.
Basically, what I was trying to do is create accessToken using firebase and pass it to verifyIdToken which was wrong.
Later when I have written a web application and received a idToken by google login using firebase and passed it to this method at backend it worked.
I don’t know how but, your id token string is not passed fully, make sure you are passing whole string of Id token.