【发布时间】:2014-01-21 00:28:28
【问题描述】:
我们的 Marketplace 应用的一项功能是通过 IMAP 访问用户的 Gmail 帐户。我们正在使用 google-api-java-client 和 google-oauth-java-client 库和类似于this example in the java-gmail-imap project 的代码如下:
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_ID)
.setServiceAccountScopes(Arrays.asList(GMAIL_SCOPE))
.setServiceAccountPrivateKey(PRIVATE_KEY)
.setServiceAccountUser(emailAddress)
.build();
credential.refreshToken();
然后我们使用基于https://code.google.com/p/google-mail-oauth2-tools 示例的代码来建立 IMAP 连接,例如
IMAPStore imapStore = OAuth2Authenticator.connectToImap("imap.googlemail.com",
993, emailAddress, credential.getAccessToken(), false);
在大多数情况下,这似乎可以正常工作,但是我们看到,对于少量但大量的请求,refreshToken() 对 Google 的调用失败并出现 HTTP 500 错误和 HTML 响应,其中 JSON 会通常会被退回,例如
<p class="large"><b>500.</b> <ins>That's an error.</ins></p>
<p class="large">The server could not process your request.
<ins>That's all we know.</ins></p>
Google 的一位开发者倡导者告知我们,服务帐户不支持刷新令牌,我们应该使用this example 中的方法。
然而,似乎没有调用refreshToken然后accessToken没有填充在凭证对象上,然后当我们调用OAuth2Authenticator.connectToImap时这会导致NullPointerException p>
从GoogleCredential 的源代码看来,executeRefreshToken() 似乎被覆盖以处理服务帐户,即它不执行刷新,它只是请求一个新令牌,然后Credential 中的这段代码然后处理填充访问令牌:
TokenResponse tokenResponse = executeRefreshToken();
if (tokenResponse != null) {
setFromTokenResponse(tokenResponse); ....
我们不确定是否需要将对 refreshToken() 的调用包含在重试循环中以解决间歇性 500 错误,或者我们是否需要对代码进行其他更改以遵循针对这种情况的推荐方法。
谁能给点建议?
【问题讨论】:
标签: google-apps-marketplace google-oauth-java-client