使用 Google Cloud Endpoint (Java) 的内置身份验证时,如何获取当前用户的 Google+ 配置文件?

How can you get the Google+ Profile of the current user when using Google Cloud Endpoint's (Java) built in authentication?

我的设置

后端: Google App Engine (Java) w/ Google Cloud Endpoints 使用 Endpoint 的内置身份验证

前端: AngularJS 网络应用程序

问题

我需要为我的用户获取 Google+ 配置文件。关键字 "me" 通常可用于获取当前用户的 Google+ 配置文件,但是由于 Google Cloud Endpoints 中的所有身份验证都是在幕后完成的,我看不到无论如何为当前用户获取凭据,也不是令牌。所有你得到它的 com.google.appengine.api.users.User 对象。

使用 Google Cloud Endpoint 的内置身份验证时,是否有任何方法可以获取用户凭据或访问令牌?

注意:Google+ 配置文件 ID 与 Google 帐户 ID 不同。

可能的解决方案

我可以只使用带有关键字 "me" 的 Google+ JS 客户端,让用户发送他们的 Google+ ID,然后存储它并将其绑定到他们的 Google 帐户 ID,但这将是非常不安全的,因为用户可以破解他们的方式来发送任何 Google+ 帐户的 ID。

使用 Google Cloud Endpoint 的内置身份验证时可以获得用户访问令牌。

  1. 将参数 HttpServletRequest request 添加到您的 Google 云端点,如下所示。这将允许您获得原始请求。

  2. 然后您需要检索名为 Authentication 的 header。这将获得一个 Bearer 访问令牌,允许您构建凭据来模拟经过身份验证的用户。

  3. 接下来您将使用该 Bearer 访问令牌构建 com.google.api.client.googleapis.auth.oauth2.GoogleCredential object。您将需要它来构建 Plus 服务。

  4. 使用 Plus 构建器使用您刚刚创建的凭据构建 Plus 服务object。

示例代码

@ApiMethod(path = "myPath")
public void myEndpoint(HttpServletRequest request, ParmOne paramOne, ...) throws OAuthRequestException {

    if (user == null) {
        throw new OAuthRequestException("Authentication error!");
    }

    GoogleCredential credentialAsUser = new GoogleCredential().setAccessToken(request.getHeader("Authorization").substring(7)); // Start string at index position 7 to remove prefix "Bearer" from token.

    Plus plus = new Plus.Builder(new UrlFetchTransport(), new JacksonFactory(), credentialAsUser).setApplicationName("my-app").build();
    Person profile = plus.people().get("me").execute();

}

文档

可以找到 Google Plus 客户端的 Java 文档 here

有关创建 Google 凭证的说明的 Java 文档可以在 here.

中找到

Android 客户的补充回答

问题

除了 Marc 的回答之外,重要的是 GoogleCredentials-Object 在 request-header.

中需要一个 access_token

如果您使用 apiExplorer 或 javascript endpoint, this token is already served in the Authorization-header. But if you follow the docs for an android client 调用端点,您的请求 header 包含 id_token,因此 GoogleCredentials.setAccessToken 不起作用。

解决方案

要将授权类型更改为 access_token,只需在 Android 中使用 usingOAuth2 而不是 [=20= 创建您的 GoogleAccountCredential-Object ].

例子

在您的 Android 应用程序中替换此代码

credential = GoogleAccountCredential.usingAudience(this,
"server:client_id:1-web-app.apps.googleusercontent.com");

有了这个

credential = GoogleAccountCredential.usingOAuth2(this, 
Collections.singleton(Scopes.PLUS_LOGIN));

并将其发送到您的 Api,正如 documentation

所解释的那样
Helloworld.Builder helloWorld = new Helloworld.Builder(AppConstants.HTTP_TRANSPORT,
  AppConstants.JSON_FACTORY,credential);