GoogleCredential OAuth访问令牌invalid_grant错误

时间:2015-07-24 20:54:07

标签: google-oauth google-api-java-client

我试图通过服务帐户为谷歌的存储API获取2条腿的oauth2访问令牌。

相关文件包含在此处: https://developers.google.com/identity/protocols/OAuth2ServiceAccount

我首先尝试通过HTTP / REST api获取令牌。我最终放弃了无法通过以下细节获得400响应:

  

{"错误" :" invalid_grant" }

然后我转向推荐的方法:使用java Google api客户端库(我使用scala)。

val credentialBuilder = new GoogleCredential.Builder()
  .setTransport(GoogleNetHttpTransport.newTrustedTransport())
  .setJsonFactory(JacksonFactory.getDefaultInstance())
  .setServiceAccountId(Configuration.GoogleAPI.ServiceAccount.email)
  .setServiceAccountPrivateKeyFromP12File(new File(Configuration.GoogleAPI.ServiceAccount.pkcs12))
  .setServiceAccountScopes(Collections.singleton(StorageScopes.DEVSTORAGE_FULL_CONTROL))

def updateToken = {
  val credential = credentialBuilder.build()
  credential.refreshToken()
  // ... do stuff here with token
}

运行上面的命令,我得到一个TokenResponseException,其有效负载与我直接访问REST api的错误相同。 400 Bad Request,invalid_grant错误。

进行一些研究(在stackoverflow和其他地方),我发现此错误消息的最常见原因是:

1)本地时钟未与Google的服务器同步。当我使用REST api时,我甚至怀疑这一点,因为我之前遇到过其他服务的这个问题。我很确定它不是时钟问题,因为我已经多次将我的时钟与外部ntp服务器同步:

  

sudo ntpdate -s ntp.ubuntu.com

2)此错误的另一个常见原因是错误地设置了服务帐户客户端ID。大多数人将其设置为其服务帐户客户端ID(以" apps.googleusercontent.com"结尾)而不是其服务帐户客户端电子邮件。很明显,这不是问题所在,因为我正确地指向了电子邮件(文档指示了这一点,所以我遵循了指示),结束于" @ developer.gserviceaccount.com&# 34。

我被困住了。我检查了用户文档,javadocs,各种论坛。错误消息非常有用(可能是这样设计的,因为它是一个安全端点)。

存在此错误的其他可能原因是什么?我该怎么做才能获得我的服务帐户访问令牌?

1 个答案:

答案 0 :(得分:0)

如果您使用OAuth2.0访问Google Analytics(分析)帐户,则可能还有一个原因是获取invalid_grant。根据{{​​3}}:

  

如果应用程序尝试使用无效的刷新令牌,则为   返回invalid_grant错误响应。每个独特的限制   对OAuth 2.0客户端和Google Analytics帐户进行25次刷新   令牌(请注意,此限制可能会有所变化)。如果申请   继续请求同一客户/帐户对的刷新令牌,   一旦发出第26个令牌,第一个刷新令牌就是   以前发出的将失效。第27次请求刷新   令牌会使先前发出的第二个令牌无效,依此类推。