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?