
Amazon S3(Amazon Simple Storage Service)는 데이터를 버킷 내 객체로 저장하는 객체 스토리지 서비스이다. '객체'는 해당 파일을 설명하는 모든 메타 데이터를 의미하며 '버킷'은 객체에 대한 컨테이너이다.
참고 >> AWS S3 문서
Multer는 파일을 업로드하기 위해 사용되는 multipart/form-data를 다루기 위한 node.js 미들웨어이다.
multer-s3는 AWS S3를 위한 multer 참고 >> multer-s3 문서
Bucket 생성
새로운 bucket을 생성할 때, 퍼블릭에서 파일에 접근하는 것을 허용하기 위해서 퍼블릭 엑세스 차단을 해제해주어야 한다.
IAM 설정


사용하려는 이름을 작성하고 직접 권한 정책을 AmazonS3FullAccess를 설정한다.
multer에 대한 설정
import multer from 'multer'
import multerS3 from 'multer-s3'
import aws from 'aws-sdk'
import dotenv from 'dotenv'
import s3AccessKey from '../configs/s3'
dotenv.config()
const { AWS_S3_ACCESS_ID, AWS_S3_ACCESS_KEY, AWS_S3_REGION } = s3AccessKey
//aws 설정
aws.config.update({
accessKeyId: AWS_S3_ACCESS_ID,
secretAccessKey: AWS_S3_ACCESS_KEY,
region: AWS_S3_REGION,
})
const s3 = new aws.S3() as any
export const upload = multer({
storage: multerS3({
s3: s3,
bucket: 'movie-inner', //생성한 버킷 이름
acl: 'public-read', // 소유자는 모든 권한, 유저는 읽기 권한만
contentType: multerS3.AUTO_CONTENT_TYPE,
key: function (req, file, cb) {
cb(null, `${Date.now()}_${file.originalname}`)
}, //파일명 : 현재 시각_파일명
}),
// 파일 크기 제한
limits: { fileSize: 5 * 1024 * 1024 },
})
Image 업로드
export const uploadImage = async (req: Request, res: Response) => {
const multerFile = req.file as Express.MulterS3.File
const imageURL = multerFile.location
const imageName = multerFile.key
const imageSize = multerFile.size
if (imageURL) {
res.status(200)
res.json({
success: true,
imageName: imageName,
imageSize: imageSize,
imageURL: imageURL,
})
} else {
res.status(400)
res.json({
success: false,
})
}
}
Image 삭제
export const deleteImage = async (req: Request, res: Response) => {
const { imageName } = req.body // 객체 URL
const imageArray = imageName.split("/")
const imageKey = imageArray[3] // Image Key
const params = {
Bucket: "movie-inner",
Key: imageKey,
}
console.log(imageKey)
try {
await s3.deleteObject(params, function (err: AWSError, data: any) {
//존재하는 key가 없음
if (err) {
res.status(400)
res.json({
success: false,
error: err,
})
//성공적으로 삭제
} else {
res.status(201)
res.json({
success: true,
deleted: imageKey,
})
}
})
//추가 에러
} catch (e) {
console.error(e)
res.status(400)
res.json({
success: false,
error: e,
})
}
}
Router 등록
const router = express.Router()
router.post('/', upload.single('image'), uploadImage)
router.delete('/', deleteImage)
middleware 등록
app.use("/image", router)
참고 자료 :