我正在尝试通过Google App Engine提供的App Identity界面使用Google Drive API。这基本上允许我的web应用程序从服务器到服务器与谷歌的API进行通信。
我不需要我的用户登录,我只需要显示我自己的谷歌硬盘文档。
然而,在我设置了所有适当的值和范围,并在控制台页面上启用了所有正确的Google Drive旋钮之后,我仍然可以通过向https://www.googleapis.com/drive/v2/files
:发出简单的get请求来获得它
{ "error": { "errors": [ { "domain": "usageLimits", "reason": "dailyLimitExceededUnreg", "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.", "extendedHelp": "https://code.google.com/apis/console" } ], "code": 403, "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup." }}
怎么了?我错过了什么?以下是实际执行请求的代码-有趣的是,如果我使用其他API,例如URL缩写器API:,它会非常有效
var scopes = new java.util.ArrayList();
scopes.add("https://www.googleapis.com/auth/drive");
var appIdentity = AppIdentityServiceFactory.getAppIdentityService();
var accessToken = appIdentity.getAccessToken(scopes);
var url = new URL("https://www.googleapis.com/drive/v2/files");
var connection = url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("GET");
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Authorization", "OAuth " + accessToken.getAccessToken());
编辑
例如,如果我简单地将API更改为使用urlshortner
API,它就可以工作:
var url = new URL("https://www.googleapis.com/urlshortener/v1/url/history");
输出:
{ "kind": "urlshortener#urlHistory", "totalItems": 0, "itemsPerPage": 30}
那么谷歌硬盘和应用程序标识肯定有什么不起作用?
编辑2
我从这里的正确答案中找到了一些帮助:https://stackoverflow.com/a/12526286/50394
但它讨论的是在谷歌应用程序上设置客户端API范围,我不使用谷歌应用程序,我只是使用谷歌应用引擎的域foo.appspot.com
您得到的403错误意味着您的GET中没有Authorization头。其逻辑是,如果没有Authorization头,你就是匿名的(你就是军团之类的:-)。匿名使用的驱动器配额为零,因此出现消息。URL shortener对匿名者有更高的配额,所以它可以工作。
我建议您更改URL以指向自己的http服务器,并检查您实际发送的标头。
AFAICT您应该在Authorization标头中使用Bearer
。
可能发生的情况是,Drive API无法识别服务帐户(因为标头错误?),因此将其视为匿名请求,因为也没有提供key
参数(请参阅常见查询参数)。
试试这个:
connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken());
或者,您可以尝试将令牌添加为access_token
查询参数。
我认为您至少应该设置一个API控制台条目,并在https://code.google.com/apis/console一旦你创建了这个,你就会得到一个可以在GoogleCredential对象中使用的ID。从GoogleCredential对象中,您可以获得访问令牌,然后将其添加到您的请求中。
我在这里读到的(Google通过服务帐户驱动)是,您使用了一种略有不同的风格,使用了从开发人员控制台检索的API密钥
对我来说,相关的部分是生成"服务器应用程序密钥",然后使用这种技术,我在其他任何地方都没有读过!
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
AppIdentityCredential credential =
new AppIdentityCredential.Builder(DriveScopes.DRIVE).build();
// API_KEY is from the Google Console as a server API key
GoogleClientRequestInitializer keyInitializer =
new CommonGoogleClientRequestInitializer(API_KEY);
Drive service = new Drive.Builder(httpTransport, jsonFactory, null)
.setHttpRequestInitializer(credential)
.setGoogleClientRequestInitializer(keyInitializer)
.build();
这个答案声称:
Drive SDK不支持服务帐户,因为安全模型。
如果这仍然是真的,一种解决方法是使用常规的Google帐户执行一次常规的OAuth舞蹈,并在数据存储中保留访问和刷新令牌。