Node.js

[Node.js] multer-s3를 이용한 AWS s3 파일 업로드

itaeiou 2022. 1. 20. 15:59
반응형

multer-s3를 이용한 AWS S3 파일 업로드 구현하기

node.js 서버에서 multer-s3를 이용해 S3로 파일을 업로드하는 방법을 알아보겠습니다.

S3버킷이 생성, IAM설정 등 AWS에 관한 내용은 따로 설명하지 않겠습니다.

multer-s3 : https://www.npmjs.com/package/multer-s3

 

multer-s3

Streaming multer storage engine for AWS S3

www.npmjs.com

 

모듈 설치

multer, multer-s3, aws-sdk 모듈이 필요합니다.

  • multer. multer-s3 : 파일 업로드 모듈
  • aws-sdk: AWS 서비스 연결 모듈
npm install multer multer-s3 aws-sdk

 

S3 객체 생성

const AWS = require('aws-sdk');

const s3 = new AWS.S3({
    accessKeyId: "myAccessKeyId",
    secretAccessKey: "mySecretAccessKey",
    region: "ap-northeast-2"
})

주의! accessKeyId와 secretAccessKey 값은 외부로 노출되면 안되기 때문에 git 업로드시 별도 파일(config, env 등)을 생성해서 gitignore 설정해야 합니다.

 

upload 미들웨어 작성

const multer = require('multer');
const multerS3 = require('multer-s3');
const moment = require('moment');

const storage = multerS3({
    s3: s3,
    acl: 'public-read-write',
    bucket: "s3 버킷명",   // s3 버킷명+경로
    key: (req, file, callback) => {
    	let dir = req.body.dir;
        let datetime = moment().format('YYYYMMDDHHmmss');
        callback(null, dir + datetime + "_" + file.originalname);  // 저장되는 파일명
    }
});

const upload = multer({ storage: storage });
  • s3 : 위에서 생성한 S3 객체
  • acl : 파일 엑세스 권한
    • private : default, 버킷 소유자만 읽기/쓰기 가능
    • public-read : 읽기만 가능, 쓰기 불가능
    • public-read-write : 읽기/쓰기 모두 가능
  • bucket : 버킷 이름. '버킷명/폴더명' 형식으로 경로 작성 가능.
  • key : 파일명. 버킷 대신 '폴더명/파일명' 형식으로 경로 작성 가능.

 

router 코드 작성

router.post('/upload', upload.single('file'), async (req, res) => {
    let saveFile = req.file;
    let params = [saveFile.originalname, saveFile.key, saveFile.location, saveFile.contentType];

	...
});

 

Front 코드 작성

const upload = async (uploadFile, dir) => {
    if (uploadFile) {
        const formData = new FormData();
        formData.append('dir', dir);
        formData.append('file', uploadFile);

        await axios
            .post('/upload', formData)
            .then((response) => {
                if (response.status === 200) {
                    data = response.data;
                }
            })
            .catch(err => {
            	console.log(JSON.stringify(err));
        	});
    }

    return data;
}

await upload(uploadFile, '/profile');

file을 담아 보낼 땐, FormData에 담아서 보냅니다.

혹시 back 서버에서 받을 때, req.body가 undefined로 나온다면 formData append 순서를 바꿔주세요.

순서에 따라 req.body가 완전히 채워지지 않아 값이 보이지 않을 수 있다고 합니다. 참고링크

 

결과

profile 폴더에 잘 저장된 것을 보실 수 있습니다.

반응형