Suhail Pappu
Suhail Pappu

Reputation: 39

POST 403 forbidden CORS response when uploading an image to AWS S3 bucket ReactJS

Hello so I am trying to upload images to AWS S3 from my React application using an NPM package called react-s3. I am using an AWS Educate account and have setup the access and secret key correctly. After I select the image and console log the output it gives me a 403 forbidden error as follows.

POST https://shopkartimages.s3.amazonaws.com/ 403 (Forbidden)

Response {type: "cors", 
url: "https://shopkartimages.s3.amazonaws.com/", 
redirected: false, 
status: 403, ok: 
false, …}
body: (...)
bodyUsed: false
headers: Headers
__proto__: Headers
ok: false
redirected: false
status: 403
statusText: "Forbidden"
type: "cors"
url: "https://shopkartimages.s3.amazonaws.com/"
__proto__: Response

My bucket policy is as follows :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3Permissions",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": "arn:aws:s3:::shopkartimages/*"
        }
    ]
}

My CORS configuration in S3 is as follows:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]

Upvotes: 3

Views: 2762

Answers (2)

Peter
Peter

Reputation: 1432

I ran into this exact same problem with react-s3. I finally abandoned it in favor of AWS SDK which works fine for me (even in react). Here's what it took.

First install aws-sdk:

$ npm install aws-sdk

Then replace whatever you were doing with react-s3 with this:

import AWS from 'aws-sdk';

AWS.config.update({ region:region, credentials: new AWS.Credentials(secret_id, secret_access_key)});
var s3 = new AWS.S3({apiVersion: "2006-03-01", params: { Bucket: bucketName }});

let upload_params = {Bucket: bucketName, Key: file.path, Body: file};
let upload = new AWS.S3.ManagedUpload({params: upload_params});
let promise = upload.promise();
promise.then(
    function(data){console.log("Successfully uploaded:", file.path);},
    function(err){console.log("Failed to upload", file.name, "with error:", err.message);}
);

Here's my CORS stuff from S3 Bucket Permissions:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]

Also, public access is blocked and I'm not messing around with custom bucket policies.

Hope this helps someone else dealing with these CORS/S3/react nightmares.

Upvotes: 0

Atul Sharma
Atul Sharma

Reputation: 10665

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3Permissions",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": "arn:aws:s3:::shopkartimages/*"
        }
    ]
}

Your bucket policy only allow Get & List operations. And uploading a file is a PUT operation.

Upvotes: 1

Related Questions