Flutter Firebase Auth — проблема с проверкой токена на сервере PHP

#php #firebase #flutter #firebase-authentication #jwt

#php #firebase #flutter #firebase-аутентификация #jwt

Вопрос:

Я использую аутентификацию Firebase в своем приложении Flutter для управления пользователями (Facebook, Google, электронная почта …). Когда пользователь входит в мое приложение, я отправляю токен Firebase на мой PHP-сервер, где этот токен проверяется с помощью JWT.

Проблема в том, что, хотя токен, сгенерированный при входе по электронной почте, правильно проверен, токен, сгенерированный при входе в Facebook или Google, завершается ошибкой с «SignatureInvalidException: проверка подписи не удалась».

Код входа в Facebook в приложении Flutter:

 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());

  

Информация о токене правильно проверена в https://jwt.io / debugger, так что заголовок и полезная нагрузка в порядке.

На сервере PHP (один и тот же код для обоих случаев):

  • Проверка токена электронной почты и пароля (ОК):

    Объект stdClass ( [iss] => https://securetoken .google.com/project-123546 [aud] => project-123546 [auth_time] => 1603424825 [user_id] => S2gpfdsa156dsacdsfQ2z1 [sub] => S2gpfdsa156dsacdsfQ2z1 [iat] => 1603424825 [exp] => 1603428425 [email] => user@example.com [email_verified] => [firebase] => Объект стандартного класса ([идентификаторы] => Объект стандартного класса ([email] => Массив ([0] => user@example.com ) ) [sign_in_provider] => пароль ) )

  • Проверка токена Facebook (KO):

    Фатальная ошибка: неперехваченная Firebase JWT SignatureInvalidException: ошибка проверки подписи на сервере vendor firebase php-jwt src JWT.php: 122 Трассировка стека: # 0 servertoken.php (18): FirebaseJWTJWT::декодировать(‘eygswbdsasdJSUzI…’, ‘——BEGIN CERT …’, Массив) #1 {main}, добавленный servervendorfirebasephp-jwtsrcJWT.php в строке 122

PHP-код:

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

Идентификатор ключа совпадает с ключом в https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com , но я думаю, что приложение (или Firebase) неправильно подписывает токен закрытым ключом при входе в Facebook и Google. Тем не менее, я тоже использую auth.currentUser.getIdToken() адрес электронной почты и пароль для входа, поэтому различий нет.

Есть идеи, как это решить?

Ответ №1:

Исследуя библиотеку firebase для Flutter, я нашел ответ на эту проблему. Я публикую это здесь на всякий случай, если это кому-то помогло.

Библиотека в порядке, и подпись сгенерирована правильно. Причина совершенно не связана с библиотекой — DebugPrint() в Flutter / Dart на платформе Android не имеет достаточного буфера для распечатки всей строки токена. Итак, проблема в print(token.toString()); том, что если вы отправите токен на сервер, он будет правильно декодирован.

Вся информация об этой проблеме: https://github.com/FirebaseExtended/flutterfire/issues/2728

Ответ №2:

Я думаю, вы можете использовать log для получения всего токена:

 log(token);
  

Несмотря на то, что токен jwt каким-то образом недействителен https://jwt.io , но я все еще могу проверить его с моего серверного сервера, который является Java, используя Firebase Admin SDK.

 FirebaseAuth.getInstance(firebaseApp).verifyIdToken(token);
  

введите описание изображения здесь

Ответ №3:

Кроме того, вы можете печатать следующим образом:

 final idToken = await firebaseCredential.user!.getIdToken(true);
print(idToken.substring(0, 1000));
print(idToken.substring(1000));