我在 Google App Engine 上有一个应用程序(托管在 appspot.com 上),一些用户将使用该应用程序从 Internet 上获取一些东西,将其保存在 Datastore 中,然后将其写入 Google 电子表格。我希望使用服务帐户来访问电子表格,但是当我尝试执行任何操作时遇到 400 OK { "error" : "invalid_grant" } 问题,无论我是否尝试使用 Drive API 创建文件或使用电子表格 API 访问现有文件。
我在 API 控制台中打开了 Drive API 和 Drive SDK 并生成了 P12 密钥。这是我构建的方法GoogleCredential
:
private GoogleCredential getGoogleCredential() throws IOException, GeneralSecurityException {
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(TRANSPORT)
.setJsonFactory(FACTORY)
.setServiceAccountId("1511XXX90247.apps.googleusercontent.com")
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(
new File("05a605b0fXXXd2a6be864be15d81a2bd629d3bd6-privatekey.p12"))
.setServiceAccountUser("XXX@gmail.com") // My personal e-mail address which I used to create the project
.build();
return credential;
}
ServiceAccountID 来自 API 控制台。我已经尝试将1511XXX90247@developer.gserviceaccount.com
其用作我的 ServiceAccountUser 以及myappname@appspot.gserviceaccount.com
. 我使用的范围如下:
https://spreadsheets.google.com/feeds
https://docs.google.com/feeds
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
这是我尝试使用电子表格 API 时失败的代码:
SpreadsheetService service = new SpreadsheetService("name of my app");
service.setOAuth2Credentials(getGoogleCredential());
FeedURLFactory factory = FeedURLFactory.getDefault();
SpreadsheetQuery query = new SpreadsheetQuery(factory.getSpreadsheetsFeedUrl());
query.setTitleQuery("test");
SpreadsheetFeed feed = service.query(query, SpreadsheetFeed.class);
当服务尝试执行查询时,代码会失败。
这是我尝试过的驱动器代码,但也失败了:
Drive drive = new Drive.Builder(TRANSPORT, FACTORY,
getGoogleCredential()).build();
com.google.api.services.drive.model.File file = new com.google.api.services.drive.model.File();
file.setTitle("test");
file.setMimeType("application/vnd.google-apps.spreadsheet");
drive.files().insert(file).execute(); // This is where the code fails
无论我尝试什么,我似乎总是以同样的“无效授权”错误告终。这是部分堆栈跟踪:
com.google.gdata.util.AuthenticationException: Failed to refresh access token: 400 OK { "error" : "invalid_grant" }
at com.google.gdata.client.GoogleAuthTokenFactory$OAuth2Token.refreshToken(GoogleAuthTokenFactory.java:260)
at com.google.gdata.client.GoogleAuthTokenFactory.handleSessionExpiredException(GoogleAuthTokenFactory.java:702)
at com.google.gdata.client.GoogleService.handleSessionExpiredException(GoogleService.java:738) at com.google.gdata.client.GoogleService.getFeed(GoogleService.java:680)
at com.google.gdata.client.Service.query(Service.java:1237)
at com.google.gdata.client.Service.query(Service.java:1178)
at spam.gwt.scraper.server.spreadsheets.APIConnector.doGet(APIConnector.java:66)
我试图到处寻找答案,包括但不限于Google Developers Spreadsheets Guide、这个Service Account-related Stack Overflow question和这个Google App Engine-specific Stack Overflow question。随着发展(例如 Docs -> Drive)的发展,很难找到最新的信息,更不用说专门与 GAE 相关的信息了。