简体   繁体   中英

Google cloud troubleshot with signed url in navigator and react

I'm trying to upload a file on google cloud storage bucket with an url signed. I generate this url signed on a java server-side api (lagom and scala, but use the java library of google) like this:

    def generateV4GPutObjectSignedUrl(objectId: String, bucketTempName : String): String = {
    // Define Resource
    val blobInfo = BlobInfo.newBuilder(BlobId.of(bucketTempName, objectId)).build
    // Generate Signed URL
    val extensionHeaders : HashMap[String, String] = new HashMap();
    extensionHeaders.put("content-type", "application/x-www-form-urlencoded");

    val url = storage.signUrl(blobInfo, timeSignedUrl, TimeUnit.SECONDS, Storage.SignUrlOption.httpMethod(HttpMethod.PUT),
        Storage.SignUrlOption.withExtHeaders(extensionHeaders), Storage.SignUrlOption.withV4Signature())

    url.toString
  }

On my client-side reactjs, I try to use this url with Axios: ''' const file = this.state.file; const url = new URL(this.state.urlToUpload);

    const options = {
        params : url.search,
        headers : {
            "Content-Type" : file.type,
            /*"X-File-Name" : this.state.tenantId + "-" + this.state.id,*/
            /*"Content-Length" : file.size,*/
            //"access-control-allow-origin" : "*"
        },
        
    }
    console.log(options);
    let callback = function (response) {
        console.log(response);
        // handle success
        this.setState({
            isUpload : true
        });// upload sur google qd l'état modifier
        console.log("upload finished");
    };
    callback =  callback.bind(this);


    console.log("upload begin");
    axios.put(url.href, file, options).then(callback)
    .catch(function (error) {
      // handle error
      console.log(error);
    })
    .then(function () {
      // always executed
    });

''' I've setup my bucket CORS like this:

[
    {
      "origin": ["http://localhost:3000"],
      "responseHeader": ["Content-Type", "X-File-Name", "Content-Length", "access-control-allow-origin", "Authorization", "User-Agent", "x-goog-resumable", "Accept-Encoding", "Accept-Language", "Connection", "Host", "Origin", "Referer", "TE", "Accept"],
      "method": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
      "maxAgeSeconds": 1800
    }
]

I've tested different content-type (always same client-side and server-side). For all this test, the Option preflight http request is ok like that:

HTTP/2 200 OK
x-guploader-uploadid: AAANsUkl4OZVmEX_cBGT2Wd363YoJd6mcG_59hY7TgPH4lupm38VXEHXRYkYVt6nzOb7synkbkRExV45KlJfqBzMiNZwYTQt0w
access-control-allow-origin: http://localhost:3000
access-control-max-age: 1800
access-control-allow-methods: GET,POST,PUT,DELETE,OPTIONS
access-control-allow-headers: Content-Type,X-File-Name,Content-Length,access-control-allow-origin,Authorization,User-Agent,x-goog-resumable,Accept-Encoding,Accept-Language,Connection,Host,Origin,Referer,TE,Accept
vary: Origin
date: Wed, 08 Jul 2020 13:03:52 GMT
expires: Wed, 08 Jul 2020 13:03:52 GMT
cache-control: private, max-age=0
content-length: 0
server: UploadServer
content-type: text/html; charset=UTF-8
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
X-Firefox-Spdy: h2

but the put request failed with a 403 error code and CORS missing Allow Origin:

HTTP/2 403 Forbidden
x-guploader-uploadid: AAANsUmuMK8iiw99CGz7ldrcHZR_GkBttiMEBo_tBeR5-GpchMWT8InuNVGa2TfAdiCsDGuQUXF93PH1F98K7PG-rQDYQcLtUQ
content-type: application/xml; charset=UTF-8
content-length: 1697
date: Wed, 08 Jul 2020 13:04:02 GMT
server: UploadServer
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
X-Firefox-Spdy: h2

I've try the same request with the same header on Postman, I don't have any error and the file is upload correctly. I've try to disable CORS with extension on navigator, it removes the CORS error, but the error 403 is still here. I think that google don't add "access-control-allow-origin" in the header.

With XMLHttpRequest and FormData, it resolve the problem.

handleIdAndUrlReceived() {
        const file = this.state.file;
        const url = new URL(this.state.urlToUpload);
        var xhr = new XMLHttpRequest();
        const formData = new FormData();

        for(let e in url.search){
            formData.append(e, url.search[e]);
        }

        formData.append("file", file);

        xhr.open("PUT", url.href);
        xhr.setRequestHeader('Content-Type', file.type);
        xhr.send();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM