0
votes

I am using Firebase authentication in my Flutter app to manage the users (Facebook, Google, Email...). When the user log in my app, I send the Firebase token to my PHP server, where that token is verified with JWT.

The problem is that, although the token generated by the email login is correctly verified, the token generated by the Facebook or Google login fails with "SignatureInvalidException: Signature verification failed".

Facebook login code in the Flutter app:

FirebaseAuth auth = FirebaseAuth.instance;
final LoginResult result = await FacebookAuth.instance.login();

final FacebookAuthCredential facebookAuthCredential = FacebookAuthProvider.credential(result.accessToken.token);
UserCredential user = await auth.signInWithCredential(facebookAuthCredential);

String token = await auth.currentUser.getIdToken();
print(token.toString());

The information of the token is correctly validated in the https://jwt.io/ debugger, so the header and the payload are fine.

In the PHP server (Same code for both cases):

  • Validating the email&password token (OK):

    stdClass Object ( [iss] => https://securetoken.google.com/project-123546 [aud] => project-123546 [auth_time] => 1603424825 [user_id] => S2gpfdsa156dsacdsfQ2z1 [sub] => S2gpfdsa156dsacdsfQ2z1 [iat] => 1603424825 [exp] => 1603428425 [email] => [email protected] [email_verified] => [firebase] => stdClass Object ( [identities] => stdClass Object ( [email] => Array ( [0] => [email protected] ) ) [sign_in_provider] => password ) )

  • Validating the Facebook token (KO):

    Fatal error: Uncaught Firebase\JWT\SignatureInvalidException: Signature verification failed in server\vendor\firebase\php-jwt\src\JWT.php:122 Stack trace: #0 server\token.php(18): Firebase\JWT\JWT::decode('eygswbdsasdJSUzI...', '-----BEGIN CERT...', Array) #1 {main} thrown in server\vendor\firebase\php-jwt\src\JWT.php on line 122

PHP code:

$token = "...TOKEN-FROM-APP...";
$pkeys_raw = file_get_contents('https://www.googleapis.com/robot/v1/metadata/x509/[email protected]');
$pkeys = json_decode($pkeys_raw, true);
$decoded = JWT::decode($token, $pkeys, ["RS256"]);
print_r($decoded);

The KeyID match with the key in https://www.googleapis.com/robot/v1/metadata/x509/[email protected], but I think that the app (or Firebase) is not signing correctly the token with the private key in the Facebook and Google login. However, I am using auth.currentUser.getIdToken() too in the email&password login, so there are not differences.

Any idea how to resolve this?

1

1 Answers

0
votes

Investigating in the firebase library for Flutter I found the answer to this problem. I post it here just in case it was helpfull for someone.

The library is fine and the signature is correctly generated. The reason is totally unrelated to the library - debugPrint() in Flutter/Dart on the Android platform does not have enough buffer to print out the entire token string. So the problem is the print(token.toString());, if you send the token to the server it will be correctly decoded.

All the info about this issue: https://github.com/FirebaseExtended/flutterfire/issues/2728