Hi! Are you ready to take your file storage to the next level? Amazon S3 (Simple Storage Service) is an amazing cloud storage solution that makes it super easy for developers to securely store and retrieve files. In this blog, we’ll guide you through the fun process of integrating AWS S3 with your NestJS application for safe file storage. We’ll cover all the essentials like installation, configuration, file uploads, and access control, complete with some cool example code. Let’s get started!
Prerequisites
Before we start, make sure you have:
- Node.js installed
- NestJS project set up (
npm i -g @nestjs/cli && nest new my-app
) - AWS Account with S3 bucket created
- IAM user with appropriate permissions
Step 1: Install Required Dependencies
Run the following command to install AWS SDK and file management dependencies:
npm install @aws-sdk/client-s3 @nestjs/config multer multer-s3
-
@aws-sdk/client-s3
: AWS SDK for interacting with S3 -
@nestjs/config
: Manage environment variables -
multer
: Middleware for handling file uploads -
multer-s3
: Integrates Multer with AWS S3
Step 2: Configure AWS S3 in NestJS
2.1: Add AWS Credentials in .env
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_REGION=us-east-1
AWS_BUCKET_NAME=your_bucket_name
2.2: Create s3.service.ts
Create a service to handle file uploads.
import { Injectable } from '@nestjs/common';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { ConfigService } from '@nestjs/config';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
export class S3Service {
private s3: S3Client;
private bucket: string;
constructor(private configService: ConfigService) {
this.s3 = new S3Client({
region: this.configService.get<string>('AWS_REGION'),
credentials: {
accessKeyId: this.configService.get<string>('AWS_ACCESS_KEY_ID'),
secretAccessKey: this.configService.get<string>('AWS_SECRET_ACCESS_KEY'),
},
});
this.bucket = this.configService.get<string>('AWS_BUCKET_NAME');
}
async uploadFile(file: Express.Multer.File) {
const key = `uploads/${uuidv4()}-${file.originalname}`;
const params = {
Bucket: this.bucket,
Key: key,
Body: file.buffer,
ContentType: file.mimetype,
ACL: 'private', // Secure access
};
await this.s3.send(new PutObjectCommand(params));
return { key, url: `https://${this.bucket}.s3.amazonaws.com/${key}` };
}
}
Step 3: Implement File Upload Controller
Create upload.controller.ts
:
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { S3Service } from './s3.service';
@Controller('upload')
export class UploadController {
constructor(private readonly s3Service: S3Service) {}
@Post()
@UseInterceptors(FileInterceptor('file'))
async uploadFile(@UploadedFile() file: Express.Multer.File) {
return this.s3Service.uploadFile(file);
}
}
Step 4: Secure File Access
To ensure secure access, restrict S3 permissions:
- Public Access Block: Ensure your bucket is private.
- Presigned URLs for Secure Access:
Add the following method in s3.service.ts:
import { GetObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
async getSignedUrl(key: string) {
const command = new GetObjectCommand({
Bucket: this.bucket,
Key: key,
});
return getSignedUrl(this.s3, command, { expiresIn: 3600 }); // 1 hour expiry
}
Step 5: Test the API
Upload a File
curl -X POST -F "file=@/path/to/file.jpg" http://localhost:3000/upload
Get Secure File URL
Modify upload.controller.ts
:
@Get('secure/:key')
async getSecureFile(@Param('key') key: string) {
return this.s3Service.getSignedUrl(key);
}
Now, access your file securely with http://localhost:3000/upload/secure/{file-key}
.
Hope you find it helpful!
Using S3 Bucket in NestJS to Store Files