0
votes

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

2

2 Answers

0
votes

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
        }

    };

}
0
votes

I got it. I used the code below:

it worked for me, I know that it's not good because I am sending a Token Bearer. I tested your solution and worked too, thanks. Your solution is better, because you are using api google.

function sentStorage(token, bucket, x-goog-project-id) {
       var file =  document.getElementById("myFile").files[0];
       var url = 'https://www.googleapis.com/upload/storage/v1/b/'
       url += bucket + o?uploadType=media&name=' + file;
       xhr = new XMLHttpRequest();

       xhr.open('POST', url);
       xhr.setRequestHeader('Content-Type', file.type);

       xhr.setRequestHeader('x-goog-project-id', x-goog-project-id);
       xhr.setRequestHeader('Authorization', 'Bearer ' + token);

       xhr.send(file);

       xhr.onreadystatechange = function () {
           if (xhr.readyState === 4) {
               var response = JSON.parse(xhr.responseText);
               if (xhr.status === 200) {
                   alert('codigo 200');
               } else {
                 var message = 'Error: ' + response.error.message;
                 console.log(message);
                   alert(message);

               }
           }
       };
   }