Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to connect to AWS S3 from React App

EDIT

I've found out through the comments that I was querying the general S3 api instead of the specific buckets api. Doing that from a browser does not work and I got the error I reported here. In order to "fix" that, I simply switched to using the specific buckets API.

I used the same configurations, but instead I called the s3.upload method as in:

  const uploadFile = (file) => {
    const uploadParams = { ACL: "public-read", Bucket: config.bucketName, Key: file.name, Body: file };

    s3.upload(uploadParams, function (err, data) {
      if (err) {
        console.log("Error", err);
      } else {
        console.log("Success", data.Location);
        // setProfilePic(data.location)
      }
    })
  }

I want to upload a file to S3 from my React app. I am using the "official" aws-sdk module, from following this tutorial: https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html#s3-example-creating-buckets-scenario

The problem is that I am getting a CORS error right in my first attempt to print my buckets:

import AWS from 'aws-sdk'

const config = {
  bucketName: 'train-my-game',
  dirName: 'profile', /* optional */
  region: 'us-east-2',
  accessKeyId: proccess.env.ACCESS_KEY,
  secretAccessKey: proccess.env.SECRET,
}

AWS.config.update({ region: config.region, accessKeyId: config.accessKeyId, secretAccessKey: config.secretAccessKey });
const s3 = new AWS.S3({ apiVersion: '2006-03-01' });

const printBuckets = () => {
  s3.listBuckets(function (err, data) {
    if (err) {
      console.log("Error", err);
    } else {
      console.log("Success", data.Buckets);
    }
  });
}
printBuckets()

This fails with the error: Access to XMLHttpRequest at 'https://s3.us-east-2.amazonaws.com/' from origin 'http://localhost:3000' 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.

In the AWS, my bucket is configured with the following permission XML for the CORS configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Does anyone know how to fix this?

Thank you

like image 710
brauliopf Avatar asked Sep 03 '25 10:09

brauliopf


1 Answers

To put objects to a bucket, list objects in a bucket, retrieve bucket policies etc. you need to enable CORS on the target S3 bucket. Read the CORS documentation or see the example at awslabs/aws-js-s3-explorer.

You will not be able to invoke ListBuckets, however. The reason is that the ListBuckets call is made to an S3 service endpoint (s3.amazonzaws.com), not to an S3 bucket endpoint (bucket.s3.amazonaws.com) and you cannot enable CORS on the S3 service endpoint. So, ListBuckets will never work in a regular browser. Some browsers allow you to suppress CORS, but it's not normal browser operation. Obviously, if your app were to run outside of the browser, e.g. as a CLI or in Electron, then ListBuckets would work fine.

like image 56
jarmod Avatar answered Sep 05 '25 00:09

jarmod