Related:
Amazon S3 direct file upload from client browser - private key disclosure
https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html
In a rest endpoint:
import aws from 'aws-sdk'
export default async function handler(req, res) {
try {
// 1.
const s3 = new aws.S3({
accessKeyId: process.env.APP_AWS_ACCESS_KEY,
secretAccessKey: process.env.APP_AWS_SECRET_KEY,
region: process.env.APP_AWS_REGION,
})
// 2.
aws.config.update({
accessKeyId: process.env.APP_AWS_ACCESS_KEY,
secretAccessKey: process.env.APP_AWS_SECRET_KEY,
region: process.env.APP_AWS_REGION,
signatureVersion: 'v4',
})
console.log('bucket: ' + process.env.AWS_S3_BUCKET_NAME)
// 3.
const post = await s3.createPresignedPost({
Bucket: process.env.AWS_S3_BUCKET_NAME,
Fields: {
key: req.query.file,
},
Expires: 60, // seconds
Conditions: [
['content-length-range', 0, 5048576], // up to 1 MB
],
})
console.log('post req: ' + JSON.stringify(post))
// 4.
return res.status(200).json(post)
} catch (error) {
console.log(error)
}
}
The constructed url is invalid:
bucket: 'arn:aws:s3:::my-app-bucket' # Will be used in an API route.
post req: {"url":"https://s3.eu/'arn:aws:s3:::my-app-bucket' %23 Will be used in an API route."
Is this the right way of authenticating to aws?
Code:
const uploadPhoto = async (e) => {
const file = e.target.files[0];
const filename = encodeURIComponent(file.name);
const res = await fetch(`/api/upload-image?file=${filename}`);
const data = await res.json();
const formData = new FormData();
console.log("uploadPhoto()");
console.log("file " + JSON.stringify(file));
console.log("filename " + filename);
console.log("data " + JSON.stringify(data));
// @ts-ignore
Object.entries({ ...data.fields, file }).forEach(([key, value]) => {
formData.append(key as string, value as string);
});
toast.promise(
fetch(data.url, {
method: "POST",
body: formData,
}),
{
loading: "Uploading...",
success: "Upload successful",
error: `Upload failed ${error}`,
}
);
};
Logs:
uploadPhoto()
admin.tsx?6c2c:49 file {}
admin.tsx?6c2c:50 filename user.png
admin.tsx?6c2c:51 data {"url":"https://s3.eu/'arn:aws:s3:::my-app' %23 Will be used in an API route.","fields":{"key":"user.png","bucket":"'arn:aws:s3:::my-app' # Will be used in an API route.","X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":"AKIAZMB5ZBK2LSTW23DT/20221025/EU (Frankfurt) eu-central-1/s3/aws4_request","X-Amz-Date":"20221025T133228Z",