Unity / Android ServerAuthCode在后端没有idToken

时间:2016-08-11 19:12:40

标签: google-app-engine servlets unity3d oauth-2.0

我有一个统一应用程序并使用google-play-games插件与google * .aar版本9.4.0。我最近将我的后端(Google App Engine)从php更改为java。我的问题如下:在php中,serverauthcode用于获取用户数据(采用JWT格式) - 它工作正常。所以我改为Java servlet,因为2天后我失败了才能获得有效的idtoken。我能够从我的应用程序接收服务器身份验证代码,并且GoogleAuthorizationCodeTokenRequest会生成有效的令牌响应(请参阅代码段)。不幸的是,它不包含任何idtoken内容,但包含有效的auth_token。所以我无法获得用户ID来识别用户。当我调用tokenResponse.parseIdToken();它失败了NullPointerException。

servlet代码(authCode是我从Unity内部的play-games-plugin发送到我的GAE的serverAuthCode):

// (Receive authCode via HTTPS POST)

// Set path to the Web application client_secret_*.json file you downloaded from the
// Google Developers Console: https://console.developers.google.com/apis/credentials?project=_
// You can also find your Web application client ID and client secret from the
// console and specify them directly when you create the GoogleAuthorizationCodeTokenRequest
// object.
String CLIENT_SECRET_FILE = "/mypath/client_secret.json";

// Exchange auth code for access token
GoogleClientSecrets clientSecrets =
    GoogleClientSecrets.load(
        JacksonFactory.getDefaultInstance(), new FileReader(CLIENT_SECRET_FILE));
GoogleTokenResponse tokenResponse =
          new GoogleAuthorizationCodeTokenRequest(
              new NetHttpTransport(),
              JacksonFactory.getDefaultInstance(),
              clientSecrets.getDetails().getTokenUri(),
              clientSecrets.getDetails().getClientId(),
              clientSecrets.getDetails().getClientSecret(),
              authCode,
              REDIRECT_URI)  // Specify the same redirect URI that you use with your web
                             // app. If you don't have a web version of your app, you can
                             // specify an empty string.
              .execute();

String accessToken = tokenResponse.getAccessToken();

// Get profile info from ID token -> HERE IT THROWS AN EXCEPTION.
GoogleIdToken idToken = tokenResponse.parseIdToken();
GoogleIdToken.Payload payload = idToken.getPayload();
String userId = payload.getSubject();  // Use this value as a key to identify a user.
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");

令牌响应看起来像(现在无效):

{
"access_token" : "ya29.CjA8A7O96w-vX4OCSPm-GMEPGVIEuRTeOxKy_75z6fbYVSXsdi9Ot3NmxlE-j_t-BI",
"expires_in" : 3596,
 "token_type" : "Bearer"
 }

在我的PHP GAE中,我总是在这个包含我加密数据的构造中有一个idToken。但它现在不见了?!所以我觉得我在Java中做了不同的事情,或者我在谷歌控制台上创建新的OAuth 2.0客户端时犯了一个错误。

我通过以下方式手动检查了accessToken: https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.CjA8A7O96w-vX4OCSPm-GMEPGVIEu-RTeOxKy_75z6fbYVSXsdi9Ot3NmxlE-j_t-BI

{
"issued_to": "48168146---------.apps.googleusercontent.com",
"audience": "48168146---------.apps.googleusercontent.com",
"scope": "https://www.googleapis.com/auth/games_lite",
"expires_in": 879,
"access_type": "offline"
}

有什么我看不到的吗?非常感谢帮助...

1 个答案:

答案 0 :(得分:0)

我在团结插件中找到了一个根本原因讨论" play-games-services"在github上: https://github.com/playgameservices/play-games-plugin-for-unity/issues/1293https://github.com/playgameservices/play-games-plugin-for-unity/issues/1309

谷歌似乎正在切换他们的身份验证流程。在给定的链接中,他们正在谈论在插件中添加电子邮件范围以再次获得idtoken。我会在接下来的几天里尝试一下并分享我的经验。

以下是对发生的事情的一个很好的解释: http://android-developers.blogspot.de/2016/01/play-games-permissions-are-changing-in.html

如果你做了paulsalameh在这里说的话(Link to Github),它会再次起作用:

  

paulsalameh:当然。导入unitypackage后,下载NativeClient.cs和   来自我的提交的PlayGamesClientConfig.cs(#1295&#1296),并替换   他们在正确的位置。

结识"团结游戏 - 服务 - 插件"代码更新,您将能够将AddOauthScope(" email")添加到PlayGamesClientConfiguration,这允许您的服务器再次使用serverAuthCode获取idtoken ...

Unity的代码段:

  PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
            .AddOauthScope("email")
            .AddOauthScope("profile")
            .Build();

现在我又回来了:

{
  "access_token" : "ya29.Ci8..7kBR-eBdPw1-P7Pe8QUC7e_Zv7qxCHA",
  "expires_in" : 3600,
  "id_token" : "eyJhbGciOi......I1NiE0v6kqw",
  "refresh_token" : "1/HlSZOo......dQV1y4E",
  "token_type" : "Bearer"
}