【问题标题】:Android Firebase Rest API AuthenticationAndroid Firebase Rest API 身份验证
【发布时间】:2019-06-05 05:12:17
【问题描述】:

我目前正在使用 Firebase 实时数据库开发应用程序,但是我选择不使用 SDK 从数据库中检索数据。原因是我不希望我的代码与 FireBase 如此紧密地联系在一起,因为一旦构建了应用程序,api 本身就会转移到基于自定义休息的 api。

我已经按照文档使用 REST 和 Firebase 实现了 api 调用,没有问题 - POST、GET、DELETE 等。

我遇到的问题是,如果我在数据库上启用任何类型的身份验证,根据我需要发送“access_token”和请求的文档,但是我不知道从哪里检索它。 firebaseUser.getToken(true) 返回看起来像 JWT 令牌,如果我将其发送为 "access_token" 则无法识别。我得到401 Unauthorized

我还按照说明设置了一个服务帐户,该帐户似乎生成了一个有效的令牌,但它并不能唯一地识别用户。

所以我的问题是,任何人都可以指出如何获取所需的访问令牌来标识哪个用户正在访问该 api 吗?我的 Firebase 项目支持的登录选项是 Google、Facebook 和 Twitter。

【问题讨论】:

    标签: android firebase oauth-2.0 firebase-realtime-database firebase-authentication


    【解决方案1】:

    如果您要从每一种不同的身份验证模式中寻找不同的令牌或 ID,您应该为它们中的每一种实现不同的 API:

    REST API

    要检索访问令牌,您需要使用服务帐户。请 请参阅使用 Google 服务帐户的指南。您可以创建一个 来自服务的 Firebase 项目中的服务帐户凭据 Firebase 控制台的“帐户”部分。

    例如,生成适当的 oauth2 令牌的一种方法是使用 Java google-api-client。

    GoogleCredential googleCred = GoogleCredential.fromStream(new FileInputStream("service_account.json"));
    GoogleCredential scoped = googleCred.createScoped(
        Arrays.asList(
          "https://www.googleapis.com/auth/firebase.database",
          "https://www.googleapis.com/auth/userinfo.email"
        )
    );
    scoped.refreshToken();
    String token = scoped.getAccessToken();
    

    成功的请求将由200 OK HTTP 状态代码指示。响应包含正在检索的数据:

    { "first": "Jack", "last": "Sparrow" }
    

    数据库 REST API 接受查询字符串或标头 Authorization: Bearer <TOKEN> 上的 access_token=<TOKEN> 来验证使用服务帐户的请求。

    以下示例演示了如何将其与包含用户名的数据库一起使用。您可以将 [PROJECT_ID] 替换为您的 Firebase 项目的标识符。

    脸书

    您应该将Facebook SDK 添加到您的应用程序中,并实现一个LoginButtonLoginManager 项目,作为public_profile 电子邮件请求一些信息。与Facebook SDK 一起工作很烦人。关于如何添加它的示例代码是这样的:

    // Initialize Facebook Login button
    mCallbackManager = CallbackManager.Factory.create();
    LoginButton loginButton = (LoginButton) findViewById(R.id.button_facebook_login);
    loginButton.setReadPermissions("email", "public_profile");
    loginButton.registerCallback(mCallbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {
            Log.d(TAG, "facebook:onSuccess:" + loginResult);
            handleFacebookAccessToken(loginResult.getAccessToken());
        }
    
        @Override
        public void onCancel() {
            Log.d(TAG, "facebook:onCancel");
            // ...
        }
    
        @Override
        public void onError(FacebookException error) {
            Log.d(TAG, "facebook:onError", error);
            // ...
        }
    });
    

    此外,在 Facebook 的 developers console 中,您应该创建一个帐户,使用您的应用程序包名称配置一个新项目,并为您的应用程序的调试和发布版本添加 SHA 密钥。完成所有这些操作后,您将使用方法 getAccessToken() 成功从 LoginResult 对象中检索令牌

    您可以在official documentation 中阅读更多相关信息。

    谷歌

    Google 更容易,因为它已经连接到 Firebase,您应该将 google play services 添加到 Gradle 并添加一个已配置到您的应用程序的 google services JSON 文件。您可以从 Firebase 控制台获取它。

    之后,您需要使用 JSON 文件中的 id 配置 GoogleSignInOptions 项目:

    // Configure Google Sign In
            GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestIdToken(getString(R.string.default_web_client_id))
                    .requestEmail()
                    .build();
    

    在此之后,您只需要在您的应用中对 GoogleSignInApi 进行意图并等待 onActivityResult 回调:

    private void signIn() {
            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
            startActivityForResult(signInIntent, RC_SIGN_IN);
        }
    
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
            if (requestCode == RC_SIGN_IN) {
                GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
                if (result.isSuccess()) {
                    // Google Sign In was successful, authenticate with Firebase
                    GoogleSignInAccount account = result.getSignInAccount();
                    firebaseAuthWithGoogle(account);
                } else {
                    // Google Sign In failed, update UI appropriately
                    // ...
                }
            }
        }
    

    之后,您将能够从 GoogleSignInAccount 项中检索令牌。请记住为您的应用的调试或发布版本配置不同的 SHA 密钥,否则 Google 登录将在发布版本中停止工作。

    您可以在official Firebase documentation 中阅读更多相关信息

    推特

    关于 Twitter,我没有在 Twitter 上工作过,所以目前无法真正帮助您,但我建议您查看Twitter developer documentationfirebase Twitter implementation post

    我会在家里做一些 poc 检查它的工作原理时尝试编辑它。

    关于 Firebase 令牌

    另一个需要了解的好点是 Firebase id 令牌,它在您的应用中每个用户和连接都是唯一的,允许您检查同一帐户是否尝试同时从不同设备登录,或发送 FCM Cloud Messages 在您的应用中使用在线通知。

    要检索它,您应该使用 API 和方法 FirebaseInstanceId.getInstance() 使用 FirebaseInstanceId 对象。这将在您的用户登录您的应用时为您检索一个 FirebaseInstance 唯一 ID。

    您可以使用idInstance.getToken() 检索他的令牌并将其存储在您的应用程序中,以便随时检查并以您想要的方式管理它。

    Firebase documentation about this 不是很清楚,所以我建议你使用下一个link,它对我在我的应用中实现它帮助很大。

    【讨论】:

    • 您好,感谢您提供的详细信息。但是,如果我们以 Google 为例,从 GoogleSignInAccount 项检索到的令牌不能用作 firebase REST API 的 access_token。这是我需要能够通过该方法识别用户的。
    • 当我回答你的问题时,它没有那么详细。对不起。您是否检查过官方文档以验证思想 REST API? :firebase.google.com/docs/reference/rest/database/user-auth你是否为GoogleCredential创建了范围你能发布你的代码吗?
    【解决方案2】:

    您可以在服务器中为 USER 添加一个表。 在该表中,添加诸如 firebase_token、google_token、fb_token 等字段。 当您在所有这些服务中一一注册时,请为用户更新表中的字段。 通过这种方式,您可以维护 users_info 以及所有必需的令牌。

    【讨论】:

      猜你喜欢
      • 2019-08-17
      • 2019-06-22
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      相关资源
      最近更新 更多