[Node.js] S3와 multer를 이용하여 프로필 이미지 저장하기

HoonDong_K·2023년 1월 31일
1

[project #1] movie-inner

목록 보기
6/10
post-thumbnail
post-custom-banner

S3 와 Multer


S3

Amazon S3(Amazon Simple Storage Service)는 데이터를 버킷 내 객체로 저장하는 객체 스토리지 서비스이다. '객체'는 해당 파일을 설명하는 모든 메타 데이터를 의미하며 '버킷'은 객체에 대한 컨테이너이다.

참고 >> AWS S3 문서

Multer

Multer는 파일을 업로드하기 위해 사용되는 multipart/form-data를 다루기 위한 node.js 미들웨어이다.

  • multer-s3는 AWS S3를 위한 multer

참고 >> multer-s3 문서

AWS S3 설정


  1. Bucket 생성
    새로운 bucket을 생성할 때, 퍼블릭에서 파일에 접근하는 것을 허용하기 위해서 퍼블릭 엑세스 차단을 해제해주어야 한다.

  2. 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)

참고 자료 :

https://inpa.tistory.com/

https://velog.io/@shitaikoto/Node-Multer-S3-aws-sdk

https://overcome-the-limits.tistory.com/334

profile
개발을 잘하고 싶은 개발자
post-custom-banner

0개의 댓글