Search code examples
google-cloud-platformgoogle-cloud-storagegoogle-cloud-endpoints

Google Cloud Storage Upload unauthorized


I'd like to do upload of a file to google cloud storage using javascript, I am using the google api javascript.

My bucket isn't public, I need configure the access for write but the cloud storage requires authenticate.

I tried a lot of type of configuration, but I know litte about GAE authenticate.

So, when I try to send the file, the follow message is show:

"message": "Anonymous users does not have storage.objects.create access to bucket boti-lab-dev."

Follow my code:

function start() {
  // 2. Initialize the JavaScript client library.
  gapi.client.init({
    'apiKey': 'myApiKey',
    // clientId and scope are optional if auth is not required.
    'clientId': 'xxxbug.apps.googleusercontent.com',
    'scope': 'https://www.googleapis.com/auth/devstorage.read_write',

  }).then(function() {
    // 3. Initialize and make the API request.
    return gapi.client.request({
      'method': 'post',
      'path': 'https://www.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=media&name=nameOfFile',
        'header': {
          'Authorization': 'Bearer ya29.mykey'
        }
    })
  }).then(function(response) {
    console.log(response.result);
  }, function(reason) {
    console.log('Error: ' + reason.result.error.message);
  });
};
// 1. Load the JavaScript client library.
gapi.load('client', start);

What I need create or configure? Thanks


Solution

  • The following works like a charm for me:

    1/ Add the following javascript:

    function init() {
        gapi.client.setApiKey(yourApiKey);
        window.setTimeout(checkAuth, 1);
    }
    
    function checkAuth() {
        gapi.auth.authorize({
            client_id: yourClientId,
            scope: yourApiScopes,
            immediate: true
        }, handleAuthResult);
    }
    
    function handleAuthResult(authResult) {
        if (authResult && !authResult.error) {
             //do something
        } else {
    
            $("#loginButton").click(function () {
                handleAuthClick();
            });
    
        }
    }
    
    function handleAuthClick() {
        gapi.auth.authorize({
            client_id: yourClientId,
            scope: yourApiScopes,
            immediate: false
        }, handleAuthResult);
        return false;
    }
    

    where yourApiScopes equals

    "email https://www.googleapis.com/auth/devstorage.read_write"
    

    2/ Add this line at the end of your HTML page

    <script src="https://apis.google.com/js/client.js?onload=init"></script>
    

    3/ Upload a file with the following function:

    function uploadFile(fileData, bucket) {
        var boundary = '-------314159265358979323846';
        var delimiter = "\r\n--" + boundary + "\r\n";
        var close_delim = "\r\n--" + boundary + "--";
        var reader = new FileReader();
        reader.readAsBinaryString(fileData);
    
        reader.onload = function (e) {
            var contentType = fileData.type || 'application/octet-stream';
            var metadata = {
                'name': fileData.name,
                'mimeType': contentType
            };
            var base64Data = btoa(reader.result);
            var multipartRequestBody =
                    delimiter +
                    'Content-Type: application/json\r\n\r\n' +
                    JSON.stringify(metadata) +
                    delimiter +
                    'Content-Type: ' + contentType + '\r\n' +
                    'Content-Transfer-Encoding: base64\r\n' +
                    '\r\n' +
                    base64Data +
                    close_delim;
    
            var request = gapi.client.request({
                'path': '/upload/storage/v1/b/' + bucket + '/o',
                'method': 'POST',
                'params': {'uploadType': 'multipart'},
                'headers': {
                    'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                },
                'body': multipartRequestBody
            });
    
            try {
                request.execute(function (resp) {
                    if (resp.hasOwnProperty("error")) {
                        //do something for error
                    } else {
                       //do something for success
                        }
                    }
                });
            }
            catch (e) {
               //do something
            }
    
        };
    
    }