- Go to the AWS Management Console.
- Open the S3 service.
- Click Create bucket and configure the following:
- Bucket name: Choose a unique name.
- Region: Select your preferred region.
- Leave other settings as default for now.
- Click Create bucket.
Create a policy to allow access to your bucket.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
Replace your-bucket-name
with your actual bucket name.
- Go to the Permissions tab of your bucket.
- Click Edit on Bucket policy.
- Paste the policy and save.
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "POST", "PUT", "DELETE"],
"AllowedOrigins": ["*"]
}
]
- Under Permissions, find CORS configuration.
- Click Edit and paste the configuration.
- Save changes.
- Go to the IAM Console.
- Click Users > Add users.
- Name the user (e.g.,
s3-upload-user
) and enable Programmatic access. - Attach the policy:
- Choose Attach existing policies directly.
- Select AmazonS3FullAccess.
- Complete the creation and download the access key credentials.
Copy the keys into your .env
file:
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
A signed URL allows secure, temporary access to S3 resources without exposing your secret credentials in the client application.
- dotenv: Loads environment variables from a
.env
file intoprocess.env
.- Install:
npm install dotenv
- Import:
import dotenv from 'dotenv';
- Install:
- express: A minimal Node.js framework for handling server-side routing.
- Install:
npm install express
- Import:
import express from 'express';
- Install:
- @aws-sdk/client-s3: AWS SDK for JavaScript to interact with S3.
- Install:
npm install @aws-sdk/client-s3
- Import:
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
- Install:
- @aws-sdk/s3-request-presigner: Generates presigned URLs.
- Install:
npm install @aws-sdk/s3-request-presigner
- Import:
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
- Install:
- cors: Handles Cross-Origin Resource Sharing.
- Install:
npm install cors
- Import:
import cors from 'cors';
- Install:
const s3Client = new S3Client({
region: process.env.AWS_REGION,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
}
});
const generateSignedUrl = async (fileName) => {
const params = {
Bucket: process.env.S3_BUCKET_NAME,
Key: fileName,
Expires: 60,
ContentType: 'image/jpeg'
};
return getSignedUrl(s3Client, new PutObjectCommand(params), { expiresIn: 60 });
};
Make a PUT
request from the frontend:
fetch(signedUrl, {
method: 'PUT',
headers: {
'Content-Type': 'image/jpeg'
},
body: file
});
You can confirm if the file was uploaded by listing objects in your bucket:
const listObjects = async () => {
const params = {
Bucket: process.env.S3_BUCKET_NAME
};
const data = await s3Client.send(new ListObjectsCommand(params));
console.log(data);
};
- Frontend: User selects a file.
- Backend: Generates a signed URL using AWS SDK.
- Frontend: Uses the signed URL to upload the file.
- AWS S3: Stores the file.
- Confirmation: Backend lists objects or confirms success.
Flowchart illustration:
[User] -> [Frontend App: Request Signed URL] -> [Backend: Generate Signed URL]
[Backend] -> [AWS S3: Signed URL for PUT]
[User] -> [Upload File using Signed URL] -> [AWS S3]