Search code examples
javascriptgoogle-drive-api

Google Drive API: 404 when accessing file someone else created


I'm trying to get the contents of a file located a shared drive in which I am a content manager. The scope I'm using is https://www.googleapis.com/auth/drive.file. I get 404 errors when I try to access files that are created with my app (which I know is required for the drive.file scope), but by someone else. Everything works as it should when I try to access files created by me. Here is my code:

function getJsonContent(fileId, accessToken) { 
    let url = "https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media&supportsAllDrives=true"; 
    console.log("Sending JSON read request.");
    
    return fetch(url, { 
        'headers': {'Authorization': "Bearer " + accessToken}
    })
    .then(response => {
        if (response.ok) {
            console.log("JSON read successful.");
            return response.json();
        }
        else {
            throw "JSON read unsuccessful."; 
        }
    }); 
}

Here is my authorization code:

function handleAuth(onAccept, onDenial) {

    let onSignInUpdate = function(isSignedIn) { 
        if (isSignedIn) {
            onAccept(); 
        } else {
            onDenial();
        }
    }

    gapi.load('client:auth2', function() { 
        gapi.client.init({
            apiKey: API_KEY,
            clientId: CLIENT_ID,
            discoveryDocs: DISCOVERY_DOCS,
            scope: SCOPES
        })
        .then(function() {
            gapi.auth2.getAuthInstance().isSignedIn.listen(onSignInUpdate);
            onSignInUpdate(gapi.auth2.getAuthInstance().isSignedIn.get()); //Initial update
        })
        .catch(err => {
            console.error(err);
        });
    });
}

//In another module, specific to a webpage:

function onAccept() { 
    accessToken = gapi.auth.getToken().access_token; 
    
    getJsonContent(<ACTUALFILEID>, accessToken)
    .catch(err => {
        console.error(err);
    });
}

function onDenial() {
    console.log("Permission rejected; redirecting to index.html.");
    location.replace("index.html");
}

window.onload = function() {
    handleAuth(onAccept, onDenial);
}; 

This is the file creation code:

function makeJsonFile(parentId, fileName, accessToken) { 
    let url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id&keepRevisionForever=true&supportsAllDrives=true"; 
    console.log("Sending JSON creation request.");

    let file = new Blob([JSON.stringify([])], {'type': "application/json"}); //The object is an empty array initially
    let metadata = {
        'name': fileName,
        'mimeType': "application/json",
        'parents': [parentId],
    }

    let form = new FormData();
    form.append("metadata", new Blob([JSON.stringify(metadata)], {type: "application/json"})); 
    form.append("file", file); 

    return fetch(url, { //Returns a promise that resolves with the id of the created file
        'method': "POST", 
        'headers': { 
            'Authorization': "Bearer " + accessToken
        },
        'body': form  
    })
    .then(response => {
        if (response.ok) {
            console.log("JSON created.")
            return response.json(); 
        }
        else {
            throw "JSON creation unsuccessful."; 
        }
    })
    .then(val => val.id);
}

Solution

  • Issue:

    https://www.googleapis.com/auth/drive.file only gives you access to files that YOU have opened or created with the corresponding app. See this:

    View and manage Google Drive files and folders that you have opened or created with this app.

    In this case, it is irrelevant that the file is created on a shared drive. I'm thinking you will have to use a wider scope like https://www.googleapis.com/auth/drive, unfortunately.

    Feature request:

    Also, considering your situation, I think you might be interested in this Feature Request, regarding the possibility to restrict access to a specific folder. I think that could be very useful for you if it got implemented. I'd suggest you to star that issue, both to keep track of its development and to help prioritize its implemenation:

    Reference: