Skip to content

multer s3를 이용한 S3에 파일 업로드하기

padawanR0k edited this page Jul 7, 2021 · 5 revisions
작성자 작성일시
padawanr0k 2021-07-07

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

현재 프로젝트에서는 multer를 사용해 AWS S3서비스에 업로드 하는것을 간편하게 도와주는 multer-s3를 사용하고 있습니다.


multer-s3를 사용해 구현한 미들웨어는 다음과 같습니다.

let AWS = require("aws-sdk");
const path = require("path");
// aws-sdk를 사용하기 위해서는 aws credential key가 필요합니다.
AWS.config.loadFromPath(path.join(__dirname, "../../config/awsconfig.json")); // 인증을 위한 json
let s3 = new AWS.S3();
let multer = require("multer");
let multerS3 = require('multer-s3');

/**
 * s3ImageUpload.single('picture')  사용하는곳에서는 이런식으로 사용한다.
 * 프론트에서 FormData를 사용해 전달하는데 그때 이미지를 넣은 key값을 파라미터로 전달해주면된다.
 */
let s3ImageUpload = (config) => multer({
	storage: multerS3({
		s3: s3,
		bucket: "swlabs-saver",// 버켓이름입니다.
		key: function (req, file, cb) {
			const extension = path.extname(file.originalname); // 확장자
			const filename = Date.now().toString() + extension; // 파일명을 현재 시각으로하여 중복된 이름이 없게함
			const folder = config.folder ? `${config.folder}/` : ''; // 저장할 버켓을 지정한다.
			cb(null, folder + filename)
		},
		acl: 'public-read', // 권한 설정을 "퍼블릭 읽기전용"으로 설정합니다.
		contentType: multerS3.AUTO_CONTENT_TYPE // 파일의 메타데이터중 content-type 설정을 자동으로 맞춰준다.
	})
})

module.exports = {
	s3ImageUpload
}

사용하는 컨트롤러에서는 다음과 같이 사용합니다.

const { s3ImageUpload } = require('../lib/aws/s3Uploader');
// 버켓내부에 있는 article이라는 폴더에 저장합니다.
// request에 1개의 이미지가 존재하는 경우 .single() 메소드를  사용하며 매개변수는 FormData에 지정했던 키값을 전달합니다.
router.post('/upload/image', s3ImageUpload({ folder: 'article' }).single('image'), articleCtrl.request.uploadImage)

해당 미들웨어가 정상적으로 작동한 경우 컨트롤러내부에서 request객체에 관련정보를 접근할 수 있게 file이라는 프로퍼티를 추가해줍니다.

const myRequest = async (req, res, next) => {
  console.log(req.file) // 파일정보
  ...
}

프론트에서 서버로 값을 전달할 때는 다음과 같이 전달합니다.

const payload = new FormData()
payload.append('picture', $('#picture')[0].files[0], $('#picture')[0].files[0].name);

axios({
  method: 'post',
  url: url,
  data: payload,
  headers: {
    'Content-Type': 'multipart/form-data'
  }
}).then((res) => {
...
})

Clone this wiki locally