我试图通过服务帐户为谷歌的存储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,各种论坛。错误消息非常有用(可能是这样设计的,因为它是一个安全端点)。
存在此错误的其他可能原因是什么?我该怎么做才能获得我的服务帐户访问令牌?
答案 0 :(得分:0)
如果您使用OAuth2.0访问Google Analytics(分析)帐户,则可能还有一个原因是获取invalid_grant。根据{{3}}:
如果应用程序尝试使用无效的刷新令牌,则为 返回invalid_grant错误响应。每个独特的限制 对OAuth 2.0客户端和Google Analytics帐户进行25次刷新 令牌(请注意,此限制可能会有所变化)。如果申请 继续请求同一客户/帐户对的刷新令牌, 一旦发出第26个令牌,第一个刷新令牌就是 以前发出的将失效。第27次请求刷新 令牌会使先前发出的第二个令牌无效,依此类推。