我正在使用NodeJS后端API服务器,该服务器允许前端(ReactJS / React Native)使用表单数据上载图像。这是我正在使用的代码:
const s3 = new aws.S3({
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: "us-east-1",
});
...
const upload = multer({
storage: multerS3({
s3,
bucket: process.env.AWS_BUCKET,
acl: 'private',
metadata(req, file, cb) {
cb(null, {fieldName: file.fieldname});
},
key(req, file, cb) {
cb(null, Date.now().toString() + '.png');
}
})
})
...
app.post('/upload', upload.single('photo'), (req, res, next) => {
res.json(req.file)
})
API服务器正常工作,并且使用AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
将图像上传到私有安全存储区中。
但是现在我希望能够在ReactJS或React Native上渲染该图像。您是否建议构建另一个名为/render
之类的NodeJS路由,然后以某种方式将其流式传输到后端?如果是,我该怎么办?
或者,我是否应该直接从前端渲染它,并冒着将AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
密钥暴露给用户的风险?
答案 0 :(得分:1)
解决方案很简单:
这样,用户将只能访问您从服务器+向他们发送的资产,而无需AWS API密钥(将密钥发送到浏览器将是巨大的安全漏洞)
这是非常相同的概念,例如Google Docs,Dropbox在共享链接并将其发送给他人时使用。世界上的每个人都可以阅读该链接,但是如果链接不可猜测,则只有共享该链接,才能访问资产。
答案 1 :(得分:1)
经过多次试验和错误,我发现最优雅的解决方案是让NodeJS负责与S3的通信。然后,前端将通过以下路线GET
来自NodeJS的图像:
app.get("/image/:imageId", function(req, res, next) {
var params = { Bucket: keys.AWS_BUCKET, Key: req.params.imageId };
s3.getObject(params, function(err, data) {
if (err) {
return res.send({ error: err });
}
res.send(data.Body);
});
});
为什么我认为这比 luboskmac 提出的解决方案更为优雅?
对于初学者来说,我不会在任何时候向公众公开该资产。我只是向最终用户透露NodeJS GET
路由。
第二,如果我想限制对该路由的访问,则可以简单地在NodeJS中使用passportJS
,例如,将对资产的访问限制为仅登录的用户。这在许多情况下都很有用,例如GDPR要求。
答案 2 :(得分:0)
出于隐私和安全考虑,不建议公开存储桶,请改用 Amplify。