calviners
calviners

Reputation: 137

AWS - Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

I'm really new to AWS so please bear with me :(

I'm currently making a web application that has a feature for uploading photos. I want to save these photos in S3 buckets and save a reference to them in my database. I am following this guide at the moment: http://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-photo-album.html

However, I've done everything stated in the guide (or at least I hope), but when I run the app and run the createAlbum() method, I get the error:

XMLHttpRequest cannot load https://my-bucket-name.s3-us-west-2.amazonaws.com/myalbumname/. 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:3000' is therefore not allowed access.

I made sure that permissions allowed for all users in the Bucket permissions, I updated the CORS config as instructed by the docs, and updated the role policy as well.

This is my code in terms of credentials:

var albumBucketName = 'my-bucket-name'; //not the real value, obviously
var bucketRegion = 'us-west-2';
var IdentityPoolId = 'my-identity-pool-id'; //here, too
AWS.config.update({
  region: bucketRegion,
  credentials: new AWS.CognitoIdentityCredentials({
  IdentityPoolId: IdentityPoolId
});
var s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  params: {Bucket: albumBucketName}
});

I've been trying to find a solution with no success. Does anyone know what I need to do to fix this? Any help is greatly appreciated! Thank you.

Upvotes: 8

Views: 23179

Answers (2)

STerliakov
STerliakov

Reputation: 7963

Currently AWS uses JSON for configuration, and CORS configuration equivalent to one in previous answer looks like this:

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

This can be used in AWS console directly (copy&paste into "Edit cross-origin resource sharing" area) or with aws-cli. Make sure to adjust origins for production, restricting to actual possible sources (leaving "*" for GET, if it serves some public content).

Upvotes: 1

Leon Africa
Leon Africa

Reputation: 619

CORS on S3 bucket:

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

The * in AllowedOrigin is ok for testing purposes.

Your bucket will need the temp credentials, what you can do is:

 // Set the region where your identity pool exists 
    AWS.config.region = 'us-east-1';

    // Configure the credentials provider to use an identity pool for temp 
    credentials
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'IDENTITY_POOL_ID',
    });

    // Make the call to obtain credentials
    AWS.config.credentials.get(function(){

    // Credentials will be available when this function is called.
    var accessKeyId = AWS.config.credentials.accessKeyId;
    var secretAccessKey = AWS.config.credentials.secretAccessKey;
    var sessionToken = AWS.config.credentials.sessionToken;

    var bucketName = 'bucket_name';

    var keyName = "key_name";

    var params = {Bucket: bucketName, Key: keyName, Body: 'Hello World!'};

    s3.putObject(params, function (err, data) {
    if (err)
    console.log(err)
    else
    console.log("Successfully uploaded data to " + bucketName + "/" + 
    keyName);
    });
    });

Upvotes: 5

Related Questions