使用 Firebase 身份验证进行身份验证后检索 Google 访问令牌

2023-12-01

我正在尝试检索 Google 访问令牌以访问 Google REST API,例如YouTube 数据 API来自经过身份验证的用户(使用 Firebase 身份验证)。

我已在我的应用程序的帮助下成功集成了 Google Sign-In适用于 Android 的 Firebase-UI - 身份验证图书馆。检索到的令牌FirebaseUser.getToken()方法不是 REST API 的有效 Google 访问令牌。

user.getToken(true).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
    public void onComplete(@NonNull Task<GetTokenResult> task) {
        if (task.isSuccessful()) {
            String token = task.getResult().getToken();
            // 'token' is not a Google Access Token
        }
    }
});

In Google 登录网络指南,可以通过调用获取访问令牌var token = result.credential.accessToken;,但是我在Android中找不到类似的方法。

有任何输入吗?如果我没有提供足够的信息,请在这里发表评论。谢谢 :)


您所做的方式将为您提供 firebase id 令牌,请参阅here.


您在 firebase 中会遇到三种类型的令牌:

  • Firebase ID 令牌

    当用户登录 Firebase 应用时由 Firebase 创建。这些令牌是经过签名的 JWT,可安全地识别 Firebase 项目中的用户。这些令牌包含用户的基本个人资料信息,包括用户的 ID 字符串,该字符串对于 Firebase 项目是唯一的。由于可以验证 ID 令牌的完整性,因此您可以将它们发送到后端服务器来识别当前登录的用户。

  • 身份提供商令牌

    由联合身份提供商创建,例如 Google 和 Facebook。这些令牌可以具有不同的格式,但通常是 OAuth 2.0 访问令牌。 Firebase 应用使用这些令牌来验证用户是否已成功通过身份提供商的身份验证,然后将它们转换为 Firebase 服务可以使用的凭据。

  • Firebase 自定义令牌

    由您的自定义身份验证系统创建,以允许用户使用您的身份验证系统登录 Firebase 应用。自定义令牌是使用服务帐户的私钥签名的 JWT。 Firebase 应用程序使用这些令牌的方式与使用从联合身份提供商返回的令牌非常相似。


现在,您得到的是 firebase Id 令牌,您需要的是身份提供者令牌。

获取身份提供商令牌很简单,只需比您所显示的步骤早一步即可。

那么,我们使用firebase登录google的方式就提到了here.

我将在下面添加完整的代码,该代码在用户界面中显示一个按钮,单击该按钮后,用户将登录到谷歌帐户。然后我将获取 google 访问令牌,然后将其发送到 firebase,在那里将其转换为 firebase 令牌 Id。

我假设你已经配置了android应用程序用于谷歌登录,如果没有,你可以详细说明here.


(To cut things short, just look at Step 5 below, if you have done setup already.)
Code :
  1. 配置 Google SignIn 和 GoogleApiClient :

     // Configure sign-in to request the user's ID, email address, and basic
     // profile. ID and basic profile are included in DEFAULT_SIGN_IN.
     GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(getString(R.string.default_web_client_id))
        .requestEmail()
        .build();
    
     // NOTE : 
     // The string passed to requestIdToken, default_web_client_id, 
     // can be obtained from credentials page (https://console.developers.google.com/apis/credentials).
     // There mentioned Web application type client ID is this string.
    
    
     // ... 
     // Build a GoogleApiClient with access to the Google Sign-In API and the
     // options specified by gso.
     mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this /* Activity */, this /* OnConnectionFailedListener */)
        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .build();
    
  2. 将 Google 登录按钮添加到您的应用中

    <com.google.android.gms.common.SignInButton
        android:id="@+id/sign_in_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    
  3. 设置登录点击监听器

    findViewById(R.id.sign_in_button).setOnClickListener(new OnClickListener() {
        public void onClick(View v){
            Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
            startActivityForResult(signInIntent, RC_SIGN_IN);   
        }
    });
    
  4. 覆盖OnActivityResult活动中的方法 :

    @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) {
            // Google Sign In was successful, authenticate with Firebase
            GoogleSignInAccount account = result.getSignInAccount();
            firebaseAuthWithGoogle(account); // This method is implemented in step 5.
        } else {
            // Google Sign In failed, update UI appropriately
            // ...
        }
    }
    
  5. 使用 Google SignInAccount 进行 Firebase 身份验证

    String idTokenString = "";
    ...
    private void firebaseAuthWithGoogle(GoogleSignInAccount acct) {
        Log.d(TAG, "Google User Id :" + acct.getId());
    
        // --------------------------------- //
        // BELOW LINE GIVES YOU JSON WEB TOKEN, (USED TO GET ACCESS TOKEN) : 
        Log.d(TAG, "Google JWT : " + acct.getIdToken());
        // --------------------------------- //
    
        // Save this JWT in global String : 
        idTokenString = acct.getIdToken();
    
        AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null);
        mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());
    
                    if(task.isSuccessful()){
                        // --------------------------------- //
                        // BELOW LINE GIVES YOU FIREBASE TOKEN ID : 
                        Log.d(TAG, "Firebase User Access Token : " + task.getResult().getToken());
                        // --------------------------------- //
                    }
                    // If sign in fails, display a message to the user. If sign in succeeds
                    // the auth state listener will be notified and logic to handle the
                    // signed in user can be handled in the listener.
                    else {
                        Log.w(TAG, "signInWithCredential", task.getException());
                        Toast.makeText(GoogleSignInActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                    }
                }
            });
    }
    
  6. 最后一步:Firebase 的身份验证侦听器

    private FirebaseAuth mAuth;
    private FirebaseAuth.AuthStateListener mAuthListener;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        mAuth = FirebaseAuth.getInstance();
        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if (user != null) {
                    // User is signed in
                    Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
                } else {
                   // User is signed out
                   Log.d(TAG, "onAuthStateChanged:signed_out");
                }
                // ...
            }
       };
       // ...
    }
    
    //...
    
    @Override
    public void onStart() {
        super.onStart();
        mAuth.addAuthStateListener(mAuthListener);
    }
    
    @Override
    public void onStop() {
        super.onStop();
        if (mAuthListener != null) {
            mAuth.removeAuthStateListener(mAuthListener);
        }
    }
    

所以,你的答案就在第 5 步,即在你向 Firebase 进行身份验证之前以及在 google 登录中进行身份验证之后。

希望能帮助到你 !


UPDATE :

重要的是,在步骤 1 中,您请求令牌 Id,否则在步骤 5 中,您将得到空令牌 id。更多请参见here。我已经更新了步骤 1。


UPDATE :

根据讨论,检索到的令牌是所写的 JWT 令牌here。我们需要的是谷歌访问令牌。下面的代码使用 JWT 令牌在 OAuth 后端触发并检索此访问令牌:

(注:我使用的是okhttp版本2.6.0,其他版本可能有不同的方法)

Code :

...
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormEncodingBuilder()
            .add("grant_type", "authorization_code")
            .add("client_id", "<Your-client-id>")   // something like : ...apps.googleusercontent.com
            .add("client_secret", "{Your-client-secret}")
            .add("redirect_uri","")
            .add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8") // device code.
            .add("id_token", idTokenString) // This is what we received in Step 5, the jwt token.
            .build();

final Request request = new Request.Builder()
        .url("https://www.googleapis.com/oauth2/v4/token")
        .post(requestBody)
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(final Request request, final IOException e) {
        Log.e(LOG_TAG, e.toString());                
    }

    @Override
    public void onResponse(Response response) throws IOException {
        try {
            JSONObject jsonObject = new JSONObject(response.body().string());
            final String message = jsonObject.toString(5);
            Log.i(LOG_TAG, message);                    
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
});

这是具有所需访问令牌的输出:

I/onResponse: {
          "expires_in": 3600,
          "token_type": "Bearer",
          "refresh_token": "1\/xz1eb0XU3....nxoALEVQ",
          "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMWY1Ym......yWVsUA",
          "access_token": "ya29.bQKKYah-........_tkt980_qAGIo9yeWEG4"
     }

希望现在有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Firebase 身份验证进行身份验证后检索 Google 访问令牌 的相关文章

  • 在第一个框中输入字符后,将焦点转到下一个框

    我必须实现一个应用程序 其中我设置了较小的值edittext用于输入 PIN 码和手机号码 每个编辑文本一次包含 1 个字符 现在 当我运行这个应用程序时 我发现对于每个框 我需要将焦点放在每个框上edittext 因此 在这种情况下 是否
  • 位图背景图像应支持哪些屏幕尺寸/密度组合?

    我正在编写一个应用程序 我需要一些全屏位图背景 基于我天真的阅读支持多屏 http developer android com guide practices screens support html在 Android 文档中 为了涵盖我的
  • 在Java中测试服务器是否启动的正确方法?

    简单地查看是否可以建立与网站 服务器的连接的正确方法是什么 我想要这个用于我正在编码的应用程序 如果我的网站离线 它只会提醒我 Thanks 您可以使用 HttpURLConnection 发送请求并检查响应正文中是否有该页面特有的文本 而
  • putExtra() 和 setData() 之间的区别

    putExtra 和 setData 有什么区别 我已经阅读了 android 文档 但没有太大帮助 还有之前的一个问题Intent setData 与 Intent putExtra https stackoverflow com que
  • 如何将Android中的cURL发送到REST服务

    我是 android 新手 我想从 REST 服务获取一些数据 但在初始化发送到 REST 服务的方法时遇到一些问题 您知道 REST 服务使用 cURL 来操作一些数据 POST PUT GET DELETE 现在如何在 android
  • Android SQLite 从代码中转储数据库以进行错误报告

    我正在为我的一个 Android 程序开发一种诊断工具 本质上 如果用户遇到问题 我想做一些类似 SQLite 的事情dump 参考 http www sqlite org sqlite html http www sqlite org s
  • Android 片段之间的阴影分隔符

    我有一个类似于平板电脑的 ICS Gmail 应用程序的布局 ListFragment左边是内容 右边是内容 我想知道如何构建布局 使两个片段之间有一个阴影分隔符 就像在 Gmail 应用程序中一样 如下所示 另外 由于这适用于这个问题 我
  • 使用Picasso从url保存图像?

    我正在尝试使用 API Picasso 保存图像 为了做到这一点 我正在尝试使用Target保存 但我无法完成这项工作 我怎么能这样做呢 Trying save image public static void imageDownload
  • android.view.InflateException:二进制 XML 文件行 #11:膨胀类 ImageView 时出错

    我只是尝试制作一个小的 android java xml 应用程序来计算游戏的分数 它给了我这个错误 Error inflateing class ImageView 有人知道解决方案吗 我实际上搜索了 ppl 说添加这个 android
  • 地理编码 API 与地理编码器

    在我的应用程序中 我需要使用地理编码 但我不太清楚该使用哪种方法 直到昨天我在URL中添加了参数maps googleapis com maps api geocode json address myparameter sensor fal
  • 有人可以给出一个 android 中 webview 实现的确切例子吗

    嗨 我正在使用开发 Android 应用程序WebView执行 我跟着官方安卓教程 http developer android com resources tutorials views hello webview html 在 Ecli
  • java.net.ProtocolException:流意外结束

    我面临一个奇怪的问题 并且无法调试它 我已经实现了上传数据流的逻辑 并使用 Volley 来实现相同的功能 我在HurlStack addBodyIfExistsapi 以便可以处理 application octet stream 类型的
  • 调整 SwipeRefreshLayout 高度,将 View 置于其底部

    I have SwipeRefreshLayout里面一个RelativeLayout 问题是SwipeRefreshLayout占据了屏幕上的所有位置 我需要放置一个视图after这个观点 看图片 https i stack imgur
  • 运行 Android 应用程序时出现错误

    我已经使用 Eclipse 创建了一个 Android 应用程序 但应用程序未在 AVD 上运行 它显示 不幸的是已停止工作 日志猫消息如下 07 29 04 59 50 789 W dalvikvm 784 threadid 1 thre
  • 将触摸事件从 NestedScrollView 传递到父视图

    我在 NestedScrollView 下方有一个 ViewPager 宽度一些顶部填充 以及 ClipToPadding false 和透明背景 如图像 我的 ViewPager 无法获取触摸事件并且无法工作 我怎么解决这个问题 我无法更
  • 如何向开关对象添加/更改波纹效果

    下面是我自定义的开关 红圈是默认的波纹效果 我发现设置一个波纹可绘制作为开关的背景 控制波纹的颜色
  • Android项目中使用java获取电脑的IP地址

    我在用ksoap2 android http code google com p ksoap2 android 我需要使用java获取IP地址 这样我就不必每次都手动输入它 我所说的 IP 地址是指 例如 如果我这样做ipconfig使用命
  • android 中的 java.net.URL ..新手问题

    我是java新手 正在尝试android开发 以下代码生成 malformedURLException 有人可以帮助我识别异常吗 任何提示都会非常有帮助 package com example helloandroid import and
  • Android Volley - 发布请求 - 无法在线工作

    我试图通过 Volley 发出 POST 请求 它在我的本地主机中工作得很好 但是当我将它移动到网络服务器时 响应为空 Java代码 RequestQueue queue Volley newRequestQueue this String
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m

随机推荐