Amplify-js: Use Storage without Credentials

Created on 26 Jul 2018  路  17Comments  路  Source: aws-amplify/amplify-js

This is a question/feature request.

Currently when using the Storage library requires having credentials for Cognito on the AWS account to access a public bucket. The bucket can be accessed and listed using HTTP get but not with Storage.

What have is a bucket in another AWS account that I need access to and I don't want to have to duplicate it to the AWS account that the app is authenticated through. Is it possible to use Storage without credentials?

Storage feature-request

Most helpful comment

How can Storage credentials be defined without exposing them on the front end?

All 17 comments

Hi @rogueturnip

For now the Storage category always look for credentials. I'll talk to the team about supporting your use case.

The category internally uses the low-level aws-sdk S3 client; meanwhile you can try that (see this example)

var s3 = new AWS.S3();
var params = {Bucket: 'myBucket', Key: 'myKey'};
s3.getSignedUrl('getObject', params, function (err, url) {
  console.log("The URL is", url);
});

Thanks.

In our set up we are using AWS Organizations to seperate our environments but want to store common files at the top level or so we don't have to copy them around and potentially miss something.

Hi, I have the same issue too. All I need is to upload some pictures and videos to aws s3 bucket. I have this configuration, but it doesn't work since it requires to pass auth for Cognito.

Amplify.configure({
    Storage: {
        bucket: 'xxxxx',
        region: 'us-east-1',
        credentials: {
            accessKeyId: 'xxx',
            secretAccessKey: 'xxx'
        }
    }
});

@anjmao can you try just configuring Storage like this.

Storage.configure({
        bucket: 'xxxxx',
        region: 'us-east-1',
        credentials: {
            accessKeyId: 'xxx',
            secretAccessKey: 'xxx'
        }
    });

Hi there,
I'm back on this problem. I tried the above configuration with IAM credentials and I'm still getting an access denied on the list even with the bucket being a public bucket. I can use the failed get url and access it from the browser directly.

I also noticed the documentation has the configure JSON slightly different so I tried that with no luck:
Storage.configure({
AWSS3: {
bucket: '',//Your bucket name;
region: ''//Specify the region your bucket was created in;
}
});

Figured it out from looking at the amplify storage code. You can't define credentials in the configure, it's not used at all but you an assign the credentials directly to each call (get, list, put) like this:
let result = Storage.list('', {credentials: {
accessKeyId: 'xxx',
secretAccessKey: 'xxx'
}});

I think the credentials should also be supported at the storage level so it keeps the code cleaner.

This also means you can't use any of the components (S3Album) because you can't pass in a credentials prop in this setup.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

How can Storage credentials be defined without exposing them on the front end?

+1

+1

Assume that I have created s3 bucket and got a token, and that token I had put in front-end to upload files to s3.
is there any feature like that, so that I won't have to expose credentials.

I think something has to be provided for the following use case:

Assume a public S3 bucket which files are readable by an authenticated user, but also a not-authenticated user (e.g. no credentials are available). A public S3 bucket/folder is listable by using a simple plain HTTP request without any signed url (confirmed to work just by browsing)

So when doing Storage.list on such a key , the error should not be this (which happens now), but it should correctly list the contents as they are public!

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>InvalidAccessKeyId</Code><Message>The AWS Access Key Id you provided does not exist in our records.</Message><AWSAccessKeyId>undefined</AWSAccessKeyId> 

If anyone is looking for a workaround until this has been resolved:

Note: The bucket policy must state that the bucket is public readable and listable ("Action": "s3:ListBucket")

  axios.get("https://<bucketname>.s3.eu-central-1.amazonaws.com/?prefix=<key>, {
              headers: {
                "Content-Type": "application/json"
              },
              params: {}
            }).then(res => {
              var parser = new DOMParser();
              var xmlDoc = parser.parseFromString(res.data,"text/xml");
              console.log("Manually parse XML")
            });

Hey, any update in this? Can we use storage without Cognito?

anjmao posted already how to use it without cognito (secretkey) - but be aware that anyone can write to your folder if you deploy the secretkey to your client-side package , so be sure to use this method only with node.js server-side

If you mean a public s3 bucket, you can also use axios like i posted, but it depends what you want to do .. read or write..

@masbaehr - Thanks. I already tried that but it was showing no credentials while uploading.

Storage.configure({
bucket: 'xxxxx',
region: 'XXX',
credentials: {
accessKeyId: 'xxx',
secretAccessKey: 'xxx'
}
});

Was this page helpful?
0 / 5 - 0 ratings

Related issues

callmekatootie picture callmekatootie  路  3Comments

rayhaanq picture rayhaanq  路  3Comments

oste picture oste  路  3Comments

rygo6 picture rygo6  路  3Comments

lucasmike picture lucasmike  路  3Comments