Reputation: 3438
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
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
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