为啥 requestIdToken 返回 null?

Posted

技术标签:

【中文标题】为啥 requestIdToken 返回 null?【英文标题】:why is requestIdToken returning null?为什么 requestIdToken 返回 null? 【发布时间】:2016-03-10 18:44:56 【问题描述】:

我关注了below steps as this link

    我将 google-services.json 下载到我的应用文件夹中。

    我的项目级 gradle 文件:

    dependencies 
        classpath 'com.android.tools.build:gradle:1.3.0'
        classpath 'com.google.gms:google-services:1.5.0-beta2'
    
    

    我的应用级 gradle 文件:

    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies 
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile 'com.google.android.gms:play-services-identity:8.3.0'
        compile 'com.google.android.gms:play-services:8.3.0'
        compile 'com.google.android.gms:play-services-plus:8.3.0'
        compile 'com.google.android.gms:play-services-auth:8.3.0'
        ...
    
    

    我为我的后端服务器创建了 OAuth 2.0 客户端 ID,并将此客户端 ID 传递给 strings.xml 文件。

    最后我创建了 GoogleSignInOptions 和 GoogleApiClient 对象,如下所示:

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(getString(R.string.server_client_id))
            .build();
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();
    

    但问题是 result.isSuccess() 在 handleSignInResult 函数中总是返回 false。我在想也许我在第一步或第二步做错了什么。我的代码几乎与SignInActivity.java 相似。任何帮助将不胜感激。

【问题讨论】:

IdToken 我想是github.com/googlesamples/google-services/blob/master/android/… 我做了同样的事情,它是有效的客户端服务器 ID,但在 onActivityResult 函数中 result.isSuccess() 再次返回 false。 我建议您阅读我在***.com/questions/34099208/google-sign-in-idtoken/… 的回答,希望对您有所帮助! 不要更新google-services.json :) 我在创建凭据时更改了 OAuth 2.0 客户端 ID Web 应用程序名称,使其与我的 Android 客户端 ID 名称不同。多亏了你,它现在可以工作了。 【参考方案1】:

正如我对以下问题的回答:

Google Sign-In requestIdToken returns null

为了成功请求Id Token,你应该使用“Web application”类型的Client Id,而不是“Android”类型的Client Id。

您还可以在Google's documentation 找到以下信息(请注意#3):

为您的后端服务器创建 OAuth 2.0 客户端 ID

如果您的应用通过后端服务器进行身份验证或访问 Google 来自后端服务器的 API,您必须创建 OAuth 2.0 客户端 ID 为您的服务器。创建 OAuth 2.0 客户端 ID:

    打开凭据页面。 单击添加凭据 > OAuth 2.0 客户端 ID。 选择Web 应用程序。 点击创建。

将此客户端 ID 传递给 requestIdToken 或 创建 GoogleSignInOptions 对象时的 requestServerAuthCode 方法。


3 月 26 日更新:

Android Developers Blog - Registering OAuth clients for Google Sign-In

【讨论】:

这是访问令牌吗? @neobie 这是一个用于后端身份验证的令牌,请阅读android-developers.blogspot.com/2016/03/…,但是,我从未尝试过使用GoogleIdTokenVerifier,您可以在android-developers.blogspot.com/2016/01/… 找到更多信息。关于访问 Google API 的访问令牌,同样在该链接中,您将找到另一个指向 android-developers.blogspot.com/2016/02/… 的链接 @neobie 另一个不错的链接是developers.google.com/identity/sign-in/android/…,请注意If all you need is the user's ID, email address, name, or profile picture URL, use the ID token flow.If your server needs to access other Google APIs, such as Google Drive, Youtube, or Contacts, use the server auth code flow.,在那里你会发现另外2个链接有一些示例代码 你救了我的命。谢谢@BNK 没关系,我查看了文档并意识到我的错误。无论如何谢谢..【参考方案2】:

就我而言,我以前有过y,

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

我通过添加 requestToken 方法来修复它,

 GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestIdToken(getString(R.string.default_web_client_id))
            .build();

现在它对我有用。希望这可以帮助遇到像我这样的问题的人。

【讨论】:

我遇到了同样的问题,这解决了它。此修复程序在发布 apk 上也能正常工作吗? 是的,它有效。但是对于发布,不要忘记输入您的发布 sha1 密钥。 在 google api 控制台中对吗?我在 api 控制台中更新它。我是否也必须将发布 sha 放入代码中? 是的,如果您使用的是 firebase,那么在创建项目时或者只是添加您的发布 sha1 密钥。@wick.ed 我现在面临同样的问题,已经两天了,我已经将我的应用程序发布到谷歌游戏商店但现在我想删除注册并简单地添加谷歌登录但它给了我错误,在实现调试或发布时我应该使用什么 sha1 键?我将在哪里指定这个密钥?我在 firebase 中使用 release sha1 键。【参考方案3】:

我们可以使用带有“WebApplication ClientID”的requestServerAuthCode方法,并创建一个获取访问令牌的方法,如下所示;

 new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)

                    .requestServerAuthCode("WEBAPPLICATION CLIENT ID")

                    .requestEmail()

                    .build())

如我们所见,我们需要一个 WEBAPPLICATION CLIENT ID,我们可以从 https://console.developers.google.com;

obtain web application client id as follows

void fetchGoogleAuthToken()

    OkHttpClient okHttpclient = new OkHttpClient();
    RequestBody requestBody = new FormEncodingBuilder()
            .add("grant_type", "authorization_code")
            .add("client_id", "812741506391-
              h38jh0j4fv0ce1krdkiq0hfvt6n5amrf.apps.googleusercontent.com")
            .add("client_secret", "clientSecret")
            .add("redirect_uri","")
            .add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8")
            .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();
            
        
    );

请使用 compile 'com.squareup.okhttp:okhttp:2.6.0' (ver 3-RC1 会有不同的类) 或者你可以使用任何网络框架来进行上述调用

响应成功后,您将在 log-cat 中获得以下信息:

I/onResponse: 
          "expires_in": 3600,

          "token_type": "Bearer",

          "refresh_token": "1\/xz1eb0XU3....nxoALEVQ",

          "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjQxMWY1Ym......yWVsUA",

     **"access_token": "ya29.bQKKYah-........_tkt980_qAGIo9yeWEG4"**
     

正如所见,acces_token 可供进一步使用。

【讨论】:

使用 GoogleSignInAccount.getServerAuthCode() 获取验证码以传递给上述调用 .add("code", "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8") 你是救命稻草【参考方案4】:

我也面临同样的问题。我所做的只是再次下载 google-services.json 文件,替换旧文件即可。 不知道为什么会这样,我的猜测是有变化,在覆盖之前我忘记比较了。

【讨论】:

以上是关于为啥 requestIdToken 返回 null?的主要内容,如果未能解决你的问题,请参考以下文章

GoogleSignInOptions 中的 requestIdToken 获取空指针异常

为啥 WCF/JSON 不为 null 返回值返回“null”?

为啥 returnValueMap() 返回 NULL

为啥它返回null?

为啥 decodeByteArray 返回 null?

为啥 findViewById 搜索 RecyclerView 时返回 null?