[Dev Log] Multer-S3를 이용한 이미지 업로드

공부중인 개발자·2021년 8월 16일
1

project

목록 보기
2/4

초보 개발자입니다. 틀린 내용을 보신다면 댓글로 써주시면 감사합니다.

Multer-S3 를 이용하여 프로필 사진을 업로드하기로 계획했다.

이미 많은 블로그에서 필요한 모듈이나 세팅법에 대해 설명했고 블로그를 따라서 코드를 작성했다.

필요한 모듈은 총 3가지 였다.

필요 모듈

  • multer
  • multer-S3
  • aws-sdk

multer

Multer는 파일 업로드를 위해 사용되는 multipart/form-data 를 다루기 위한 node.js 의 미들웨어
Multer는 body 객체와 한 개의 file 혹은 여러개의 files 객체를 request 객체에 추가
body 객체는 폼 텍스트 필드의 값을 포함하고, 한 개 혹은 여러개의 파일 객체는 폼을 통해 업로드된 파일들을 포함

[출처] https://github.com/expressjs/multer/blob/master/doc/README-ko.md

Multer 는 공식문서에 작성되어있는데로 파일을 업로드하기 위해 만들어진 node.js의 미들웨어이다. multer 를 이용하면 이미지,영상등의 파일을 서버에 저장할 수 있는 것이다.

multer-S3

Streaming multer storage engine for AWS S3.
This project is mostly an integration piece for existing code samples from Multer's storage engine documentation with s3fs as the substitution piece for file system. Existing solutions I found required buffering the multipart uploads into the actual filesystem which is difficult to scale.

multer-S3에 npm 문서에 나오는 내용이다. 해석에 재능이 없기에 솔직히 정확하게 무슨 말을 하는지는 알지 못했다.
하지만 완성된 코드를 보고 추측하건데 multer로 업로드되는 파일의 저장소를 S3로 향하게 해주는 모듈인 것으로 예상했다.

aws-sdk

AWS를 프로그래밍적으로 제어하는데는 많은 노력이 필요하다. 이 중에서 반복되고, 재활용 가능한 부분을 AWS 측에서 미리 개발해서 제공하고, 개발자들은 자신들의 비즈니스에 집중할 수 있도록 미리 만들어져서 제공되는 도구들의 집합이 AWS SDK이다.
[출처] 생활코딩 https://opentutorials.org/course/608/3089

The version 3.x of the AWS SDK for JavaScript is generally available. For more information see the Developer Guide or API Reference.
[출처] aws-sdk npm https://www.npmjs.com/package/aws-sdk

AWS SDK는 위의 말처럼 AWS가 만들어놓은 도구들의 집합이며 multer-S3의 S3가 AWS에서 작동하기 때문에 S3를 이용하기 위해서 필요한 모듈이라고 생각했다.

const multer = require("multer");
const AWS = require("aws-sdk");
const multerS3 = require("multer-s3");

그렇기 때문에 위의 세가지 모듈이 필요했다.

가장 먼저 한 것은 AWS의 내 S3 버킷을 이용하기 위해 글로벌 구성 객체를 업데이트 및 보안 자격증명을 해야했다.

AWS.config.update({
  accessKeyId: process.env.S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
  region: "ap-northeast-2",
});

JSON으로 작성하는 블로그도 있었고 환경변수로 작성하는 블로그도 있었기에 나는 익숙한 환경변수를 이용해 엑세스키와 시크릿엑세스키를 넣어줬다.
그리고 리전은 현재 이용하고 있는 ap-northeast-2(서울)로 지정했다.

왜 엑세스키와 시크릿엑세스 키가 필요한가에 대한 궁금증이 생겼기 때문에 aws의 자료도 읽어보고 다른 블로그들도 찾아본 결과 내 아이디의 S3를 이용해야기 때문에 내 아이디의 엑세스키와 시크릿엑세스키가 필요한 것이라는 결론을 도출했다. 이용자가 이미지를 올릴 때 내 아이디의 S3 버킷을 이용하게 되므로 필요할 것이라는 이야기다. 이렇게 AWS에 정보를 업데이트하게 되면 multer-S3를 통해 이미지의 저장이 S3에서 이뤄지게 되는 것이었다.

const express = require("express");
const app = express();
const { userimage } = ("./controllers");
app.post("/user/image", userimage.upload.single("image"), userimage.sendPost);

처음 블로그에서 post에 대한 코드를 봤을 때는 기존에 알고 있는 post의 parameter가 장소, 그리고 함수인 것에 반해 이미지를 업로드할때 함수가 두개가 존재하는 것에 대한 의문감이 들었다.

const multer = require("multer");
const AWS = require("aws-sdk");
const multerS3 = require("multer-s3");

AWS.config.update({
  accessKeyId: process.env.S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
  region: "ap-northeast-2",
});

module.exports = {
  upload: multer({
    storage: multerS3({
      s3: new AWS.S3(),
      bucket: "ssg-ga-multer-s3",
      key: (req, file, cb) => {
        cb(null, Date.now() + "." + file.originalname.split(".").pop());
      },
    }),
    limits: { fileSize: 5 * 1024 * 1024 },
  }),

  sendPost: (req, res) => {
    try {
      let payLoad = { url: req.file.location };
      res.status(200).json({ data: payLoad });
    } catch (err) {
      console.log(err);
      res.status(500).send("sorry");
    }
  },
};

의문감을 완전히 해소하지 못하고 블로그들을 통해 확인한 코드를 보며 다시 추측을 시작했다.

upload: multer({
    storage: multerS3({
      s3: new AWS.S3(),
      bucket: "ssg-ga-multer-s3",
      key: (req, file, cb) => {
        cb(null, Date.now() + "." + file.originalname.split(".").pop());
      },
    }),
    limits: { fileSize: 5 * 1024 * 1024 },
  }),

이부분을 통해 multer와 multer-S3로 파일을 S3에 업로드를 시키고 업로드 된 파일의 저장경로(URL)을 sendPost를 통해 response 의 데이터에 넣어주게 되는것이 아닐까? 라는 추측이었다.

글을 쓰면서도 정확한 정보가 아님에 글을 쓸까말까 고민하다가 다음에 다시한번 multer 를 이용할 때 반추하기 위해서 글을 작성한다.
앞으로 코드를 작성할 때 보다 '왜' 에 중점을 둬서 왜 이렇게 작성되는지 왜 이러한 모듈이 필요한지에 대해서 확인해봐야겠다.

기회가 된다면 multer-s3를 이용하는 과정에 대해 블로깅 해봐야겠다.


참고한 사이트
Multer npm
Multer-S3 npm
AWS-SDK npm
https://juhi.tistory.com/10
https://juhi.tistory.com/11
https://morningbird.tistory.com/62

profile
열심히 공부하자

1개의 댓글

comment-user-thumbnail
2022년 11월 12일

잘 읽었습니다. 다만 기술 글이다보니 좀 더 명확하고 간결하게 쓰시면 좋을 것 같습니다. 예를 들면,
"왜 엑세스키와 시크릿엑세스 키가 필요한가에 대한 궁금증이 생겼기 때문에 aws의 자료도 읽어보고 다른 블로그들도 찾아본 결과 내 아이디의 S3를 이용해야기 때문에 내 아이디의 엑세스키와 시크릿엑세스키가 필요한 것이라는 결론을 도출했다. 이용자가 이미지를 올릴 때 내 아이디의 S3 버킷을 이용하게 되므로 필요할 것이라는 이야기다. 이렇게 AWS에 정보를 업데이트하게 되면 multer-S3를 통해 이미지의 저장이 S3에서 이뤄지게 되는 것이었다."
-> "액세스/시크릿 키는 S3 이용시 내 아이디의 권한을 얻기 위해 필요하다."

답글 달기