【问题标题】:Flutter Firebase Auth - Token verification problem in PHP serverFlutter Firebase Auth - PHP 服务器中的令牌验证问题
【发布时间】:2021-02-06 03:42:06
【问题描述】:

我在我的 Flutter 应用中使用 Firebase 身份验证来管理用户(Facebook、Google、电子邮件...)。当用户登录我的应用程序时,我将 Firebase 令牌发送到我的 PHP 服务器,在该服务器上使用 JWT 验证该令牌。

问题是,虽然通过电子邮件登录生成的令牌已正确验证,但 Facebook 或 Google 登录生成的令牌失败并显示“SignatureInvalidException:签名验证失败”。

Flutter 应用中的 Facebook 登录代码:

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/调试器中正确验证了token的信息,所以header和payload都没问题。

在 PHP 服务器中(两种情况下的代码相同):

  • 验证电子邮件和密码令牌(OK):

    stdClass 对象([iss] => https://securetoken.google.com/project-123546 [aud] => project-123546 [auth_time] => 1603424825 [user_id] => S2gpfdsa156dsacdsfQ2z1 [sub] => S2gpfdsa156dsacdsfQ2z1 [iat] => [56034248 exp] => 1603428425 [email] => user@example.com [email_verified] => [firebase] => stdClass Object ( [identities] => stdClass Object ( [email] => Array ( [0] => user@ example.com ) ) [sign_in_provider] => 密码 ) )

  • 验证 Facebook 令牌 (KO):

    致命错误:未捕获的 Firebase\JWT\SignatureInvalidException:签名验证在 server\vendor\firebase\php-jwt\src\JWT.php:122 中失败 堆栈跟踪:#0 server\token.php(18) : Firebase\JWT\JWT::decode('eygswbdsasdJSUzI...', '-----BEGIN CERT...', Array) #1 {main} 在 server\vendor\firebase\php-jwt\src 中抛出\JWT.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);

KeyID 与 https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com 中的密钥匹配,但我认为应用程序(或 Firebase)未使用 Facebook 和 Google 登录中的私钥正确签署令牌。不过我在邮箱和密码登录也是用auth.currentUser.getIdToken(),所以没有区别。

知道如何解决这个问题吗?

【问题讨论】:

    标签: php firebase flutter firebase-authentication jwt


    【解决方案1】:

    研究 Flutter 的 firebase 库后,我找到了这个问题的答案。我在这里发布它以防万一它对某人有帮助。

    库很好,签名正确生成。 原因与库完全无关——Android 平台上 Flutter/Dart 中的 debugPrint() 没有足够的缓冲区来打印出整个令牌字符串。 所以问题出在print(token.toString());,如果您将令牌发送到服务器,它将被正确解码。

    有关此问题的所有信息: https://github.com/FirebaseExtended/flutterfire/issues/2728

    【讨论】:

      【解决方案2】:

      我认为你可以使用log 来获取整个令牌:

      log(token);
      

      即使 jwt 令牌从 https://jwt.io 以某种方式无效,但我仍然能够使用 Firebase Admin SDK 从我的 Java 后端验证它。

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

      【讨论】:

        【解决方案3】:

        另外,你可以这样打印:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-31
          • 2021-12-04
          • 2017-04-15
          • 2017-10-30
          • 2022-08-16
          • 2017-06-24
          • 2021-08-26
          • 2019-02-26
          相关资源
          最近更新 更多