Search code examples
javascripthtmlgoogle-drive-apigoogle-picker

How do I use Google Picker to access files using the "drive.file" scope?


My Google Drive-integrated web application works fine with the drive scope, but using such a broad scope is bad practice unless necessary. I would like to restrict the scope to drive.file so that I can only access files created by the application and files opened using Google Picker, but I cannot get it to work.

Files created by the application can be opened without problem. Files opened using Google Picker, however, are not accessible; attempting to download such a file results in a 404 error. When I right-click the file in Google Drive and select "View authorized apps", my application is not listed as one of the authorized apps.

The code works fine if the scope is expanded to drive.

I have written a minimal test page that should download a file selected by the user in Google Picker. The process can be started by calling auth() followed by showPicker(). The key parts of the code are as follows:

gapi.auth.authorize({
    client_id: '123456789012.apps.googleusercontent.com',
    scope: 'https://www.googleapis.com/auth/drive.file',
    immediate: false
});

...

var picker = new google.picker.PickerBuilder()
    .setAppId('123456789012')
    .addView(new google.picker.DocsView(google.picker.ViewId.DOCS_IMAGES))
    .setOAuthToken(gapi.auth.getToken().access_token)
    .setCallback(onPickerAction)
    .build();
picker.setVisible(true);

...

function onPickerAction(data) {
    if ( data.action === google.picker.Action.PICKED ) {
        var id = data.docs[0].id;
        var request = new XMLHttpRequest();
        request.open('GET', 'https://www.googleapis.com/drive/v2/files/' + id);
        request.setRequestHeader('Authorization', 'Bearer ' + gapi.auth.getToken().access_token);

        request.addEventListener('load', function() {
            var item = JSON.parse(request.responseText);
            console.log(item);
        });

        request.send();
    }
}

A related question concluded that the app ID was improperly set. That does not seem to affect me; I have tested all combinations I can think of without any luck.


Solution

  • As first suggested in a Google+ conversation, the problem can be solved as follows:

    1. Make sure that the Drive SDK is enabled in the Google developer console (the Drive API is something else, and only having that enabled is not enough).
    2. Specify an "Open URL" for your application.