2

I'm trying to upload some medias on AWS S3

I have 2 applications :

  • A backend that can directly access S3 through AWS SDK
  • A frontend that needs to upload some file directly to S3

Here's how it goes :

  1. Frontend ask a Presigned Post url to the backend

  2. Backend call S3 API to get an URL and some fields (Key, Policy etc.)

  3. Frontend get those URL from backend and tries a POST on it request with the appropriate form-data

  4. I get this error :

    https://mydomain.or has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here's my CORS Configuration :

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "https://mydomain.or",
        ]
    }
]

Here's my backend code for the presigned POST :

    this.videoService.presignedPost(this.entity).toPromise().then((uploadData) => { //Where I get my URL and fields

        this.fileInput.url = uploadData.url;

        for (const [key, value] of Object.entries(uploadData.fields)) {
            event.formData.append(key, value)
        }

        this.fileInput.upload();

     });

Here's my backend code for the presigned POST :

 createPreSignedPost(entityDb) {
        let today = new Date();
        console.log(entityDb)
        return new Promise((resolve, reject) => {
            var params = {
                Bucket: BUCKET_NAME,
                Fields: {
                    key: my/key/,
                    success_action_status: '201',
                    signature_expiration: (new Date(today.getTime() + 15 * 60000))
                }
            };


     s3.createPresignedPost(params, function (err, data) {
                if (err) {
                    console.error('Presigning post data encountered an error', err);
                    reject(err)
                } else {
                    console.log('The post data is', data);
                    resolve({url: data.url, fields: data.fields})
                }
            });

What I tried :

  • The request seems to pass with Postman but nothing appears in the bucket
  • Tried the same with Chrome-unsafe (Without integrated CORS check)
  • Displayed the CORS policy and tried with curl to see what happend

The CORS configuration are OK, and when I check with curl I get blocked even though the Method and Host are allowed in my CORS Configuration.

Am I missing something?

Edit

So I checked the request that was blocked by CORS and used the exact same form-data, headers, etc. in an HTTP Client. It works just fine with the client but my app still gets blocked.

Suo
  • 43
  • 1
  • 9
  • 1
    Does you JS code work if you remove the CORS config. That will tell us if issue is the CORS or the JS settings you used. – smac2020 Jan 29 '21 at 15:40
  • If I enable all ORIGINS (And I clearly want to avoid that) in my CORS configuration, I get a net:CONNECTION_ABORTED. – Suo Jan 29 '21 at 16:40
  • 1
    I'm having the [same issue](https://stackoverflow.com/q/65963830/1380370), can't understand why nothing I try works. – amiregelz Jan 30 '21 at 13:17

2 Answers2

2

Might be nothing, but you have an invalid comma after "AllowedOrigins": ["https://mydomain.or",]. This is flagged as invalid JSON in the CORS field of the S3 bucket in the console.

bmur
  • 406
  • 2
  • 6
  • Oh sorry, actually I added this comma while writing the question, it is not present in my CORS Configuration :/ – Suo Jan 30 '21 at 15:02
1

I am sure it has to do with either one of these:

  1. your JS is not set properly.
  2. As suggested in the other answer, you CORS is not configured properly.

I tried this exact use case (no CORS in my example) and it works perfectly. To test this use case, I executed the Java V2 example that generates a pre-signed URL. See this code example:

https://github.com/awsdocs/aws-doc-sdk-examples/blob/master/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedUrlAndUploadObject.java

Next, I took the URL generated from this example and I used it to POST data from another app (that would not normally be allowed to upload).

The response was 200:

enter image description here

Look at the Java example and ensure that you have set all of the settings in your JS code.

smac2020
  • 9,637
  • 4
  • 24
  • 38
  • Hi, thanks for your detailed answer, I checked all the parameters and form data sent by the App, and It works fine from HTTP Client but still not from the app (I used the exact same request as sent by my app and disabled CORS on S3). I still can't upload anything from my app tho, I get net:CONNECTION_ABORTED. I'm still on it! – Suo Jan 30 '21 at 15:06