Multer로 S3 이미지 업로드

codeing999·2023년 6월 27일
0

Node NPM

목록 보기
14/16
post-custom-banner

참고 자료 : https://inpa.tistory.com/entry/EXPRESS-%F0%9F%93%9A-multer-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4

이미지 1개만 올릴 때

upload.single('image')

  • single을 사용.
  • image라는 변수명으로 파일을 보내야 한다고 명시.
  • req.file 에서 접근 가능.
  • S3 업로드된 주소 저장 변수 : req.file.location
{
    fieldname: 'img',
    originalname: 'hello.png',
    encoding: '7bit',
    mimetype: 'image/png',
    destination: 'uploads/',
    filename: 'hello1567238581123.png',
    path: 'uploads//hello1567238581123.png',
    size: 44933
}

이미지 여러개 올릴 때

upload.array('image', 10)

  • single 대신 array 사용.
  • 두번째 필드로 최대 갯수를 적는다.
  • req.file이 아니라 req.files에서 접근 가능.
  • S3 업로드된 주소 저장 변수 : req.files[i].location

여러 변수명으로 이미지 올릴 때

upload.fields([{ name: 'image1', limits: 5 }, { name: 'image2' }, { name: 'video' }])

  • fileds 사용
  • 각 변수명 마다 name과 limits(최대 갯수)를 적을 수 있다.
  • req.files.변수명 에서 접근 가능.
  • limit가 1인 변수명이더라도 req.files.image[0] 이렇게 길이 1의 배열로 접근해야 함.
  • S3 업로드된 주소 저장 변수 : req.files.변수명[i].location

multer 미들웨어 내에서

console.log("req.files:", req.files);
console.log("file:", file);
하면 파일을 검사해 볼 수 있다.

console.log(file) 결과

{
	fieldname: 'video',
	originalname: 'better.mp4',
	encoding: '7bit',
	mimetype: 'video/mp4'
}

이런 식으로 미들웨어 내에서 file.fielname 별로 구분하여 다른 처리를 할 수 있다.

s3에 올리기 코드

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

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

const allowedExtensions = [".png", ".jpg", ".jpeg", ".bmp", ".gif"];

const uploadImage = multer({
  storage: multerS3({
    s3: s3,
    bucket: process.env.AWS_BUCKET,
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: (req, file, callback) => {
      const userId = req.verifiedToken.userInfo; //로그인한 유저만 업로드 가능하다고 했을 때 앞의 jwt미들웨어를 이미통과하여 받은 userId

      // 확장자 검사
      const extension = path.extname(file.originalname).toLowerCase();
      if (!allowedExtensions.includes(extension)) {
        return callback(new Error("확장자 에러"));
      }
      
      //s3 경로 설정 (버킷/userId_현재시간_랜덤넘버)
      const now = moment().format("YYYY-MM-DD HH:mm:ss");
      // 임의번호 생성
      let randomNumber = "";
      for (let i = 0; i < 8; i++) {
        randomNumber += String(Math.floor(Math.random() * 10));
      }
      let s3Path = `image/${userId}_${now}_${randomNumber}`;

      callback(null, s3Path);
    },
    acl: "public-read-write",
  }),
  // 이미지 당 용량 제한 (50MB)
  limits: {
    fileSize: 10485760, //52428800,
  },
});
profile
코딩 공부 ing..
post-custom-banner

0개의 댓글