Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Drive API through Google App Engine

I'm trying to use the Google Drive API through the App Identity interface provided with Google App Engine. This basically allows my web application to communicate with Google's APIs from server to server.

I don't need my users to login, I simply need to display my own Google Drive documents.

However, after I set all the appropriate values and scopes, and enable all the right Google Drive knobs on the console page, I still get this for a simple GET request to https://www.googleapis.com/drive/v2/files:

{ "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." }}

What's wrong? What am I missing? Here's the code that actually does the request - funny thing is that it works great if I use other APIs such as the URL shortener 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());

EDIT

If I simply change the API to use the urlshortner API for example, it works:

var url = new URL("https://www.googleapis.com/urlshortener/v1/url/history");

And output:

{ "kind": "urlshortener#urlHistory", "totalItems": 0, "itemsPerPage": 30}

So there must be something not working with Google Drive and App Identity?

EDIT 2

I've found some help from the correct answer here: https://stackoverflow.com/a/12526286/50394

But it's talking about setting Client API scopes on Google Apps, and I'm not using Google Apps, I'm simply using Google App Engine's domain foo.appspot.com

like image 436
Luca Matteis Avatar asked Oct 02 '12 13:10

Luca Matteis


2 Answers

The 403 error you are getting means that there was no Authorization header in your GET. The logic is that without an Authorization header, you are anonymous (you are legion blah blah :-)). The Drive quota for anonymous use is zero, hence the message. URL shortener has a higher quota for anonymous so it works.

I suggest you change the URL to point to an http server of your own, and check what headers you are actually sending.

like image 192
pinoyyid Avatar answered Nov 09 '22 11:11

pinoyyid


AFAICT you should be using Bearer in the Authorization header.

Probably what's happening is, Drive API doesn't recognize the service account (because of the wrong header?) and thus taking it as an anonymous request since no key parameter wasn't provided either (see common query params).

Try this:

connection.addRequestProperty("Authorization", "Bearer " + accessToken.getAccessToken());

Or you could try adding the token as access_token query param.

like image 22
alex Avatar answered Nov 09 '22 12:11

alex