Suo
Suo

Reputation: 63

[AWS-S3]POST on presigned URL blocked by CORS despite CORS configuration enabling it

I'm trying to upload some medias on AWS S3

I have 2 applications :

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 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.

Upvotes: 3

Views: 4805

Answers (2)

smac2020
smac2020

Reputation: 10734

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.

Upvotes: 1

bmur
bmur

Reputation: 446

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.

Upvotes: 2

Related Questions