Nodejs

AWS-s3, multer, multer-s3를 이용한 express 파일업로드

마손리 2022. 12. 23. 03:30

Rest api 서버를 구축하고 프론트엔드에서 파일 전송을 요청해 보았다.

분명 로그를 확인했을땐 post request는 받았는데 파일은 오지 않았다. 검색을 해보니 express의 기본 기능에는 파일업로드 기능이 없어서였다.

그래서 multer라는 미들웨어와 파일을 로컬서버가 아닌 AWS-s3서버에 저장할것이기에 multer-s3도 같이 사용해보았다.

npm install multer multer-s3 aws-sdk --save

일단 multer와 multer-s3 그리고 AWS-s3를 연결하기위해 aws-sdk를 설치 후

 

aws-sdk

import aws from "aws-sdk";

const s3 = new aws.S3({
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY,
    secretAccessKey: process.env.AWS_SECRET_KEY,
  },
});

AWS-s3 서버를 개설하고 받은 access key와 secreat access key를 이용하여 연결

 

multer-s3

import multerS3 from "multer-s3";

const s3ImageUploader = multerS3({
  s3: s3,	// 위에 연결한 s3서버
  bucket: "booking-manager/imgs",  // 저장경로 
  acl: "public-read",	// 접근권한
  key: function (req, file, cb) {	// s3서버 안에서 파일이 저장될 이름
      cb(null, `${Date.now()}_${file.originalname}`);
    },
});

multer-s3를 이용하여 옵션들을 설정해주어 s3서버로 보낸다.

bucket에는 저장경로가 되는데 s3서버의 버켓명과 하위 폴더를 지정해주었다.

접근권한으로는 이미지를 불러오지만 수정할수는 없도록 설정

파일이 저장될 이름으로는 기존의 파일 이름과 업로드되는 시간을 붙여서 유니크속성을 부여했다.

 

multer

import multer from "multer";

export const uploadFiles = multer({
  storage: s3ImageUploader
})

다음으로 multer를 이용하여 미들웨어를 하나 만들어 주어야된다. 그렇지않으면 express에서는 파일을 인식하지 못한다.

설정방법은 매우 간단하다. multer를 설치해주고 storage에 multer-s3를 올려주면된다.

 

만약 AWS-s3서버를 이용하지않고 로컬서버에 직접 저장한다면 storage를 제거해주고 ' dest: "저장 경로" '를 입력해주면 된다.

 

미들웨어 연결

마지막 단계로 파일이 들어오는 express router에 미들웨어를 연결해주면 끝이난다.

 

ex)

productRouter.post(
  "/apply",
  uploadFiles.single("file"),
  postProductApply
);

 

부록

파일삭제의 경우 아래와같이 코드를 작성해주면된다.

export const handleDeletePhotoFromAWS = async(url: string) => {
  const decodedUrl = decodeURI(url);
  const Key = decodedUrl.split("amazonaws.com/")[1];
  
   await s3.deleteObject({
      Bucket:"booking-manager",
      Key
    }).promise()
};

여기서 눈에띄는것은 decodeURI이다.

우리가 파일 업로드할때 key값을 정해주면 s3서버에서는 그 key값을 자동으로 url로 encode해준다. (하긴 그래야 바로 이미지를 웹에서 사용할수 있으니...) 

그러니 우리는 프론트엔드에서 파일 url값을 받아와 decode를 해준뒤 "amazonaws.com"이후의 문자열만 빼내오면 우리가 저장한 key 값을 얻을수 있다.

그후 s3.deleteObject를 이용하여 삭제

 

중요한점은 async await과 promise() 둘다 사용해주지 않으면 작동이 안된다.

 

(깃헙:https://github.com/Mason3144/booking-manager-backend/commit/c5b60d15aab1b305df1fcf08b2e4e445ead23393#diff-5b4ca70b6087291c7dfb41bfc399d5caf440f38fda7155d4244220cf36868699)

'Nodejs' 카테고리의 다른 글

GraphQL API  (0) 2022.12.29
REST API  (0) 2022.12.26
GraphQL에서 파일 업로드  (0) 2022.12.24
GraphQl과 Apollo  (1) 2022.12.23
Express 서버에 Mysql과 session store 설치(AWS-RDS이용)  (0) 2022.12.14