[AWS] multerS3 사용해서 이미지 업로드하기

HR·2022년 7월 26일
4

AWS

목록 보기
1/3
post-thumbnail

프로젝트 진행 중 이미지를 사용하기 위해 AWS S3를 사용했다. 내가 AWS S3와 multer를 사용한 방법에 대해 기록해 보려고 한다.

AWS S3

어디서나 원하는 양의 데이터를 검색할 수 있도록 구축된 객체 스토리지

AWS 공식 홈페이지에서 확인할 수 있는 문구이다. 나는 이미지를 사용하기 위해 S3를 사용했는데, 이미지 이외에도 다양한 객체를 넣을 수 있다. 중요한 것은 버킷인데, 이곳에 원하는 데이터를 넣고 관리하며 사용할 수 있다.

만약 내가 피카츄 이미지를 버킷에 업로드한다고 치자. picka.jpg를 버킷에 담게되면 https://DOC-EXAMPLE-BUCKET.s3.us-west-2.amazonaws.com/photos/picka.jpg와 같은 형태의 url을 얻을 수 있고, 내가 원하는 곳에 url을 통해 이미지를 사용할 수 있다.

AWS S3를 사용하면서 이미지를 백업해 놓을 수 있고, 버킷에 저장해놓고 사용하기 때문에 삭제되지 않는 이상 혹시라도 이미지가 깨지는 걱정은 하지 않아도 된다는 점..!

Multer, MulterS3

multer는 multipart/form-data를 다루기 위한 node.js의 미들웨어이며, 이는 주로 파일을 업로드할 때 사용한다. multer-s3는 S3에 파일을 업로드 하도록 만들어주는 모듈이다. 다음과 같은 명령어로 설치할 수 있다.

npm install --save multer multer-s3

이미지 업로드하기

1. env 파일에 s3 키 작성하기

S3_ACCESS_KEY = "AWS에서 발급받은 액세스 키"
S3_SECRET_KEY = "AWS에서 발급받은 시크릿 키"
BUCKET_NAME = "버킷 이름"

나는 보안상 env파일에 적어놓고 사용했다.

2. S3 미들웨어 파일 작성하기

처음에는 이전 프로젝트에서 나 말고 다른 분이 s3사용한 코드가 있어서 참고하고 작성했다.

const s3 = new AWS.S3({
  accessKeyId: process.env.AWS_ACCESSKEYID,
  secretAccessKey: process.env.AWS_SECRETKEY,
});

const upload = multer({
  storage: multerS3({
    s3, // Type 'S3' is missing the following properties from type 'S3Client': destroy, middlewareStack, sendts(2739)
    bucket: process.env.BUCKET_NAME as string,
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, cb) {
      const fileId = shortId.generate();
      const type = file.mimetype.split('/')[1];
      const fileName = `${fileId}.${type}`;
      cb(null, fileName);
    },
    acl: 'public-read-write',
  }),
});

그런데 주석을 작성한 부분에서 에러가 떴다. 이전에는 잘만 동작했는데.. 여기서 멘붕이 왔다. 생각해보니까 이전 프로젝트와 다른 점은 JS와 TS밖에 없는데, TS로 인해 문제가 생긴 것이다. 열심히 구글링을 한 결과, 한 스택오버플로우 글을 찾을 수 있었다.

How to set credentials in AWS SDK v3 JavaScript?

아하.. S3Client객체의 속성인 credentials에 키값을 넣어줘야 하는구나. 그렇게 문제를 해결할 수 있었다.

import multer from 'multer';
import multerS3 from 'multer-s3';
import shortId from 'shortid';
import { S3Client } from '@aws-sdk/client-s3';

const upload = multer({
  storage: multerS3({
    s3: new S3Client({
      credentials: {
        accessKeyId: process.env.S3_ACCESS_KEY as string,
        secretAccessKey: process.env.S3_SECRET_KEY as string,
      },
      region: 'ap-northeast-2',
    }),
    bucket: process.env.BUCKET_NAME as string,
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, cb) {
      const fileId = shortId.generate();
      const type = file.mimetype.split('/')[1];
      const fileName = `${fileId}.${type}`;
      cb(null, fileName);
    },
    acl: 'public-read-write',
  }),
});

파일명은 겹치지 않도록 shortId를 사용했다. 이제 이 upload 미들웨어를 통해 내가 만든 AWS S3 버킷에 이미지를 저장할 수 있다.

  1. 이미지 업로드 라우터 작성
app.post('/test', upload.single('image'), async (req, res, next) => {
  try {
    res.status(200).json({ result: 'ok' });
  } catch (error) {
    next(error);
  }
});

다음과 같이 테스트용 라우터 코드를 작성하고, localhost:5000/test에 post요청을 보낸다.

  1. 포스트맨으로 테스트

여기서 주의할 점 두 가지가 있다.
첫 번째는 key값은 위에서 작성한 라우터의 미들웨어(upload.single('image')에 작성한 값과 동일해야 한다.
두 번째로 form-data로 전송해야 한다.

위의 조건이 만족한다면, 버킷에 내가 전송한 이미지가 업로드 되어있는 모습을 확인할 수 있다!

profile
Hello World :D

1개의 댓글

comment-user-thumbnail
2022년 9월 12일

감사합니다. 덕분에 multerS3 문제 해결하고 가요 :)

답글 달기