nrs jayaram
nrs jayaram

Reputation: 3438

How to access AWS s3 files without public access?

We are using NodeJS for Rest API's and ReactJS for an App, trying to fetch the AWS s3 images from nodeJS using aws-sdk, then planning to place into the react, the thing is the AWS Bucket does not have public access, and it should not be a public access, how to solve this problem?

From the nodeJS, we are getting s3 listObjects, can we access the image using the below object from ReactJS?

We have read a few more docs, suggested to use a signed URL but will it work in the browser to display images to the clients?

{
    "Key": "public/5db0476246e0fb0004r4rbff5/s3-c0c79f542f3c.jpg",
    "LastModified": "2019-10-23T12:30:32.000Z",
    "ETag": "\"269b2c5455h220bccc374f4f4rfee\"",
    "Size": 510811,
    "StorageClass": "STANDARD",
    "Owner": {
         "ID": "dad9f9dfk39dfijir93irjfiejfidjfjdfdfdfr3r3r3r3fef3"
    }
 }

Upvotes: 0

Views: 5898

Answers (2)

Ayyub Kolsawala
Ayyub Kolsawala

Reputation: 849

//You can use this code to make an object public while uploading it. 

const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');

//configuring the AWS environment
AWS.config.update({
    accessKeyId: "<Access Key Here>",
    secretAccessKey: "<Secret Access Key Here>"
  });

var s3 = new AWS.S3();
var filePath = "";

//configuring parameters
var params = {
  Bucket: '<Bucket Name Here>',
  Body : fs.createReadStream(filePath),
  Key : "folder/"+Date.now()+"_"+path.basename(filePath),
  ACL :'public-read'
};

s3.upload(params, function (err, data) {
  //handle error
  if (err) {
    console.log("Error", err);
  }

  //success
  if (data) {
    console.log("Uploaded in:", data.Location);
  }
});

Just add this to the call when you upload the image from your code. ACL :'public-read' (Ignore this if you dont have any upload facility).

Unfortunately for fetching objects already uploaded you cannot change the permission to public programmatically. For that please refer to this documentation https://aws.amazon.com/premiumsupport/knowledge-center/read-access-objects-s3-bucket/.

Highlighting the best possible approach for you (you can still refer the document)

Use a bucket policy that grants public read access to a specific prefix

To grant public read access to a specific object prefix, add a bucket policy similar to the following:

{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"AddPerm",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::awsexamplebucket/publicprefix/*"]
      }
  ]
}

Then, copy the objects into the prefix with public read access. You can copy an object into the prefix by running a command similar to the following:

aws s3 cp s3://awsexamplebucket/exampleobject s3://awsexamplebucket/publicprefix/exampleobject

Upvotes: 0

fzn
fzn

Reputation: 522

You can put the bucket behind CloudFront CDN. Distribute your content using signed URLs / limit access to some origins/ and anything else that might fit your use-case.

My place of work uses Cloudfront with signed URLs for the same use case.

I think this AWS help doc would help more. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

Upvotes: 1

Related Questions