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)
참고 자료 :