从 Oauth2 Google Contacts API 获取用户信息

Posted

技术标签:

【中文标题】从 Oauth2 Google Contacts API 获取用户信息【英文标题】:Get Userinfo from Oauth2 Google Contacts API 【发布时间】:2012-07-21 02:05:11 【问题描述】:

我得到的错误:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized

  "code" : 401,
  "errors" : [ 
    "domain" : "global",
    "location" : "Authorization",
    "locationType" : "header",
    "message" : "Invalid Credentials",
    "reason" : "authError"
   ],
  "message" : "Invalid Credentials"

下面的代码,我正在使用:

GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(this.TRANSPORT).setJsonFactory(this.JSON_FACTORY)
    .setClientSecrets(Constants.CLIENT_ID, Constants.CLIENT_SECRET).build();
credential.setAccessToken(tokenResponse.getAccessToken());
credential.setAccessToken(tokenResponse.getRefreshToken());

到这里,我得到了刷新令牌、访问令牌等

Oauth2 userInfoService = new Oauth2.Builder(this.TRANSPORT,
        this.JSON_FACTORY, credential.getRequestInitializer())
        .setApplicationName(Constants.APPLICATION_NAME).build();

它在以下行失败:(不知道,为什么?)

Userinfo userInfo = userInfoService.userinfo().get().execute();

我在网上搜索过,我得到的例子和稀有材料非常少。 任何机构对此有任何想法?

我做错了什么?

【问题讨论】:

【参考方案1】:

我猜 credential.getRequestInitializer() 为空。

我已经通过像这样为凭证对象设置自定义请求初始化程序来解决这个问题

GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(this.TRANSPORT).setJsonFactory(this.JSON_FACTORY)
.setClientSecrets(Constants.CLIENT_ID, Constants.CLIENT_SECRET).setRequestInitializer((new HttpRequestInitializer()
                @Override
                public void initialize(HttpRequest request)
                        throws IOException 
                    request.getHeaders().put("Authorization", "Bearer " + accessToken);
                
            )).build()

Google 的 documentation 指定以下内容:

** 例如,使用 access_token 查询字符串参数调用 UserInfo API 如下所示:

GET https://www.googleapis.com/oauth2/v1/userinfo?access_token=accessToken 使用 HTTP 标头中的访问令牌对同一 API 的调用如下所示:

GET /oauth2/v1/userinfo HTTP/1.1 授权:承载 accessToken 主机:googleapis.com**

希望对你有帮助

【讨论】:

【参考方案2】:

如果您已经获得了访问令牌(GoogleTokenResponse),那么您也可以这样做:

HttpTransport transport = new NetHttpTransport();

List<String> applicationScopes = Arrays.asList(
  PlusScopes.USERINFO_EMAIL,
  PlusScopes.USERINFO_PROFILE
);

GoogleAuthorizationCodeFlow flow
  = new GoogleAuthorizationCodeFlow.Builder(
    transport,
    JacksonFactory.getDefaultInstance(),
    "your-client-id.apps.googleusercontent.com",
    "your-client-secret",
    applicationScopes).build();

String userId = googleTokenResponse.parseIdToken().getPayload().getSubject();
Credential credential = flow.createAndStoreCredential(googleTokenResponse, userId);
HttpRequestFactory requestFactory = transport.createRequestFactory(credential);

GenericUrl url = new GenericUrl("https://www.googleapis.com/oauth2/v1/userinfo");
HttpRequest request = requestFactory.buildGetRequest(url);
String userIdentity = request.execute().parseAsString();

userIdentity 将如下所示:


  "id": "105358994046791627189",
  "name": "Benny Neugebauer",
  "given_name": "Benny",
  "family_name": "Neugebauer",
  "link": "https://plus.google.com/+BennyNeugebauer",
  "picture": "https://lh4.googleusercontent.com/-dtvDIXCEtFc/AAAAAAAAAAI/AAAAAAAAAoE/1CKd3nH9rRo/photo.jpg",
  "gender": "male",
  "locale": "de"

如果您愿意,可以使用 Jackson 将 userIdentity 解析为您自己的类:

ObjectMapper mapper = new org.codehaus.jackson.map.ObjectMapper();
mapper.readValue(userIdentity, YourUser.class);

以下是我在此示例中使用的依赖项:

<dependency>
  <groupId>com.google.apis</groupId>
  <artifactId>google-api-services-plus</artifactId>
  <version>v1-rev401-1.22.0</version>
</dependency>

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.13</version>
  <type>jar</type>
</dependency>

【讨论】:

【参考方案3】:

为了从 Userinfo API 检索数据,您必须请求访问其 OAuth 范围:

https://www.googleapis.com/auth/userinfo.profile

如果要检索电子邮件地址,还可以添加范围 https://www.googleapis.com/auth/userinfo.email

在您的代码中,我看不到您在哪里设置了您请求访问的 OAuth 范围。

【讨论】:

我也添加了该范围......并且它工作正常......授予访问权限后,我无法获得所需的响应。所以简而言之,我也包括了电子邮件范围。

以上是关于从 Oauth2 Google Contacts API 获取用户信息的主要内容,如果未能解决你的问题,请参考以下文章

通过 OAuth 2.0 和私钥(即服务帐户)访问 Google Contacts Api

Google Contacts API v3:如何使用全文查询?

Google Contacts API - 无法刷新访问令牌

带有 Google JavaScript 客户端库的 Google Contacts API

Google 通过 OAuth2 身份验证从 JavaScript 客户端联系 API 问题

使用 oauth2 从防火墙后的 Wildfly/Keycloak 安全 Web 应用程序调用 oauth2 保护 google 应用程序引擎应用程序