Google身份登录API在使用服务器客户端ID时始终返回NULL

3

[补充]

根据我的观察,我认为问题要么是与一个坏的服务器客户端ID有关,要么是需要额外的编程,而这些编程不是开箱即用的(例如应用程序引擎模块或服务器)。


[原始内容]

我已经成功地运行了Google Sign-In Android示例应用。 我遇到的问题涉及2个活动...ServerAuthCodeActivity和IdTokenActivity。

我按照创建google-services.json文件并将其放在正确位置的流程进行了操作。当我运行应用程序时,我能够成功使用提供的4个活动中的2个...

  • 登录活动:基本登录
  • 带驱动器的登录活动:基本登录加上驱动器身份验证
  • ID令牌活动:检索已登录用户的ID令牌
  • 服务器身份验证代码活动:从已验证的服务器检索身份验证代码。

前两个示例非常好用; 但是,最后两个活动只给我一个 null 结果。

在运行应用程序之前,我注意到需要在strings.xml中提供一个server_client_id。 我发现google-services.json有一个OAuth客户端ID与要求匹配(以apps.googleusercontent.com 结尾),并将该客户端ID放入strings.xml 文件中。注意:我尝试在Google开发人员控制台中创建一个Android OAuth客户端ID,但是它说我已经有了该项目/包的OAuth客户端ID。因此,我认为google-services.json 文件的客户端ID是正确的。

那么,这是正确的服务器客户端ID吗?还是我应该从其他地方获取该ID?

编辑

这是我的google-services.json 文件(压缩)

{

 "project_info": {
  ...
 },
 "client": [
   {
     "client_info": {
       ...
     },
     "oauth_client": [
       {
         "client_id": "*****.apps.googleusercontent.com", // HERE
         ...
       }
     ],
     ...
   }
 ],
 ...
}

登录后的身份验证代码结果如下图所示:


我注意到 GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 导致 result.isSuccess() 为 false。因此,似乎认证失败了...而不是认证令牌不可用。 - Christopher Rucinski
我也尝试创建一个具有自己的服务器客户端ID和密钥的Web应用程序OAuth 2.0凭据。然而,这似乎仍会导致result.isSuccess()等于false - Christopher Rucinski
你能帮我解决一下问题吗?我花了几天的时间试图解决它...我使用相同的代码,但最终当我从Google API中检索到tokenId时,我得到一个字符串tokenId = <857个字符>...??如果我尝试验证它googleapis.com/oauth2/v3/tokeninfo?access_token= <857个字符响应>,我总是得到'error_description": "Invalid Value'...你是如何验证你的响应的?你也得到一个字符串tokenId = <857个字符>吗? - Sirop4ik
4个回答

3

包名+签名证书SHA1唯一标识Android客户端。虽然Google的示例中包名是固定的,但您将不得不与您使用的签名证书一起注册它(可以来自调试密钥库或专用于测试的证书)。

此外,Web服务器需要在同一个开发控制台项目中注册一个“Web”类型的OAuth客户端,并且您必须将该oAuth客户端的客户端ID粘贴到示例代码中。从这个意义上说,您是正确的,在这种情况下,Google无法提供零附加代码的示例。

对于其他使用示例的人,您需要更改strings.xml以将您的“Web”类型OAuth客户端的客户端ID放在下面

<string name="server_client_id">YOUR_SERVER_CLIENT_ID</string>

顺便提一下,指定的server_client_id将成为id令牌或服务器授权代码中的目标受众,您可以将其传递到您的服务器。在适当的验证后,您的服务器可以信任令牌/代码。这比持有令牌更安全。您还可以查看此博客文章:http://android-developers.blogspot.com/2016/01/using-google-sign-in-with-your-server.html


如果我们仍然需要将“server_client_id”添加到字符串中,那么google-services.json有什么用处?在我看来,它只是用于参考,没有其他作用。 - Luka Bradeško
@LukaBradeško,如果您仅集成Google Sign-In,则是正确的,google-services.json不是必需的。请参阅此处的文档:https://developers.google.com/identity/sign-in/android/start-integrating#add-config。有些应用程序为开发/测试/生产环境拥有多个Web服务器OAuth2客户端(即在同一dev控制台项目中具有多个serverClientId)。因此,API明确要求提供serverClientId。 - Isabella Chen
如果您查看google-services.json文件,您会发现它仅包含客户端应用程序的OAuth客户端信息,而不包括服务器应用程序。 - Isabella Chen
你能帮我解决一下问题吗?我已经花了几天时间尝试解决它了... 我使用相同的代码,但最终当我从Google API检索tokenId时,我得到一个字符串tokenId = <857个字符>... ?? 如果我尝试验证它googleapis.com/oauth2/v3/tokeninfo?access_token= <857个字符响应>,我会得到'error_description": "Invalid Value' ... 你是如何验证你的响应的?你也得到了String tokenId = <857个字符>吗? - Sirop4ik
@Aleksey,我猜你指的是ID令牌(getIdToken())。如果你使用tokeninfo端点,请指定id_token = xxxx(而不是access_token = xxxx)。此外,要快速检查ID令牌的内容,您也可以转到jwt.io。 - Isabella Chen

3
为了获得服务器授权码,您需要请求“离线访问”。添加requestServerAuthCode(),该函数似乎需要您的服务器客户端ID(而不是您项目中任何有效的客户端ID):
String serverClientId = getString(R.string.server_client_id);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
    .requestScopes(new Scope(/* whatever scope you're needing */))
    .requestServerAuthCode(serverClientId, false)
    .build();

请参阅适用于 Android 的 Google 登录:启用服务器端访问

0

我不确定为什么会遇到这个问题,但是最终我解决了这个问题。

首先,Google提供的所有示例都可以在不需要任何额外代码的情况下工作。 (编辑:不需要添加Web服务器代码;只需提供特定的客户端ID等即可) 这是我认为的事实,但在遇到这个问题后,我对这个想法产生了质疑。我联系了一位Android开发者关系人员,他们证实了这一事实。

其次,该人还给了我以下链接,Google Sign in for Android - Start。我告诉他们我确实按照那个链接操作了,所以我认为我在开发者控制台上有一些问题导致了这个问题,创建一个新项目是我最好的选择。

解决方案

根据我所说的,如果您按照上面的链接操作并且遇到了这个问题,那么我建议您只需创建一个新项目,再次尝试。这只是一个示例项目,因此设置的数量很少,考虑到您已经完成了一次设置。


0

如果你正在使用现有的Android Studio开发项目,而该项目最初是在其他Android Studio上开发的,则可能会出现问题,因为应用程序的SHA1与你的SHA1不匹配,因此Google无法验证此应用程序,因此返回null。你必须生成自己的SHA1并获取自己的客户端ID,然后Google才会返回用户数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接