Google联系人API-刷新访问令牌失败



我们使用带有OAuth2:的Google联系人API

credential = new GoogleCredential.Builder().setTransport(new NetHttpTransport())
        .setJsonFactory(new JacksonFactory())
        .setClientSecrets(OAuth2ClientId(), OAuth2ClientSecret())
        .addRefreshListener(new CredentialRefreshListener() {...});
myService = new ContactsService("My-App");
myService.setOAuth2Credentials(credential);

我们经常收到GData库无法处理的"401未经授权"响应。当WWW-Authenticate标头丢失时,AuthenticationException引发NPE。

Caused by: java.lang.NullPointerException: No authentication header information
        at com.google.gdata.util.AuthenticationException.initFromAuthHeader(AuthenticationException.java:96) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.util.AuthenticationException.<init>(AuthenticationException.java:67) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.client.http.HttpGDataRequest.handleErrorResponse(HttpGDataRequest.java:608) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.client.http.GoogleGDataRequest.handleErrorResponse(GoogleGDataRequest.java:564) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.client.http.HttpGDataRequest.checkResponse(HttpGDataRequest.java:560) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.client.http.HttpGDataRequest.execute(HttpGDataRequest.java:538) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.client.http.GoogleGDataRequest.execute(GoogleGDataRequest.java:536) ~[gdata-core-1.0-1.47.1.jar:na]
        at com.google.gdata.client.Service.getFeed(Service.java:1135) ~[gdata-core-1.0-1.47.1.jar:1.47.1]
        at com.google.gdata.client.Service.getFeed(Service.java:1077) ~[gdata-core-1.0-1.47.1.jar:1.47.1]
        at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:676) ~[gdata-core-1.0-1.47.1.jar:1.47.1]
        at com.google.gdata.client.Service.query(Service.java:1237) ~[gdata-core-1.0-1.47.1.jar:1.47.1]
        at com.google.gdata.client.Service.query(Service.java:1178) ~[gdata-core-1.0-1.47.1.jar:1.47.1]

我们设法添加了一个包装器,尝试在这个NPE上刷新令牌。这有帮助,但仍有许多情况下刷新失败:

credential.refreshToken() == false

当我们在调试器中运行refreshToken()时,我们看到executeRefreshToken()被执行而没有异常,但tokenResponse==null被返回。结果refreshToken()返回false,并且没有任何原因传递给侦听器

try {
    TokenResponse tokenResponse = executeRefreshToken();
    if (tokenResponse != null) {
      setFromTokenResponse(tokenResponse);
      for (CredentialRefreshListener refreshListener : refreshListeners) {
        refreshListener.onTokenResponse(this, tokenResponse);
      }
      return true;
    }
  } catch (TokenResponseException e) {
    boolean statusCode4xx = 400 <= e.getStatusCode() && e.getStatusCode() < 500;
    // check if it is a normal error response
    if (e.getDetails() != null && statusCode4xx) {
      // We were unable to get a new access token (e.g. it may have been revoked), we must now
      // indicate that our current token is invalid.
      setAccessToken(null);
      setExpiresInSeconds(null);
    }
    for (CredentialRefreshListener refreshListener : refreshListeners) {
      refreshListener.onTokenErrorResponse(this, e.getDetails());
    }
    if (statusCode4xx) {
      throw e;
    }
  }
  return false;

我们的代币总是用于多个范围:https://www.googleapis.com/auth/userinfo.email https://www.google.com/m8/feeds https://www.googleapis.com/auth/calendar https://mail.google.com/ https://www.googleapis.com/auth/tasks

更新:我们已成功转移到People API,新的API也被我们的统一API联系人API使用https://docs.aurinko.io/article/25-contacts-api

联系人API中当前存在一个错误,其中某些HTTP User-Agent字符串导致401响应以HTML页而不是XML响应的形式返回,并且缺少AuthenticationException类所依赖的WWW-Authenticate头。GContacts-Java是这些特殊用户代理字符串之一。解决方法是在创建客户端后更改其用户代理:

ContactsService service = new ContactsService(applicationName);
service.getRequestFactory().setHeader("User-Agent", applicationName);

这将消除NPE,并允许客户端库自动检测过期令牌并自动刷新它们。

相关内容

  • 没有找到相关文章

最新更新