Node.js AWS S3 연동하기

by Dany


Posted on May. 24th 2019



AWS S3

S3는 아마존에서 지원하는 리소스저장소로 자세한 내용은 여기를 참고하시는게 더 좋을 것 같습니다.

일반적으로 이미지 등의 정적 리소스를 보관하는 용도로 사용합니다.

S3를 사용하는 경우, 클라이언트가 웹서버로 파일을 전송하면, 웹서버에서는 그 파일을 다시 S3로 보내서 저장하게 되는데요. 이 과정을 Node.js로 구현해보려고 합니다.

편의상, Express / Express Generator를 사용하겠습니다.

AWS계정과 S3버킷은 이미 준비되어 있음을 가정하겠습니다.

먼저, 필요한 라이브러리들을 설치합니다.

npm install aws-sdk multer multer-s3 --save

aws-sdk는 AWS 관련 sdk이고, multer는 노드에서 가장 많이 사용하는 파일 업로드 라이브러리중 하나입니다. 그리고 multer-s3는 multer와 s3를 자동으로 정말 간편하게 연결해줄겁니다.

먼저 Form에서 파일을 업로드 받을 라우터를 하나 만들겠습니다.

  • routes/index.js
...
const express = require('express');
const router = express.Router();

router.post('/uploads3', (req, res) => {
    res.send('success');
})
...

일단 라우터를 만들었습니다.

다음으로, AWS-SDK API Key를 저장하는 config.json 파일을 하나 만들어야 합니다. 그런데 주의하실점은, 이 config.json 파일은 절대로 외부로 유출되어서는 안됩니다. 프로젝트를 github 등으로 올릴때에는 반드시 .gitignore에 포함시켜서 github로 올라기지 않도록 주의해주셔야 합니다.

혹시 AWS-SDK API Key를 어디서 얻을수 있는지 모르시는 분들은, AWS API Key 얻기를 참고해주세요.

  • config.json
{
  "accessKeyId": "accessKey",
  "secretAccessKey": "secretAcessKey",
  "region": "ap-northeast-2"
}

accessKey와 secretAcessKey를 맞게 넣으시고, region은 사용하는 S3 AWS 리전인데, AWS Region Code를 참고해주시면 되겠습니다.

주의하실 점은, json의 key 이름을 정확하게 위와 같이 적어주셔야 합니다.

이제, 이 다음이 가장 중요합니다.

multer를 사용해 미들웨어를 만들건데, 이 미들웨어에서 파일을 받아다가 자동으로 s3로 전송까지 해줄겁니다.

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

Aws.config.loadFromPath(path.join(__dirname, '../config.json'));
const s3 = new Aws.S3();

const multer = require('multer');
const multer_s3 = require('multer-s3');

const upload = multer({
    storage: multer_s3({
        s3: s3,
        bucket: "bucketname",
        key: (req, file, cb) => {
            const filename_arr = file.originalname.split('.');
            const extend = filename_arr[filename_arr.length-1];
            cb(null, 'file'+'-'+new Date().now())+'.'+extend)
        },
        acl: 'public-read-write'
    })
})

코드를 순서대로 설명하자면,

  1. AWS-SDK를 가져와서 accessKey가 담긴 confg.json파일을 로드해줍니다.

  2. 그 AWS-SDK객체의 S3을 가져옵니다.

  3. multer 미들웨어를 만듭니다. 이때 storage에 multer_s3을 줍니다.

  4. multer_s3에 옵션을 지정해야 합니다. 넣어줘야 하는 옵션 정보는 다음과 같습니다.

{
    s3: 2에서 만든 s3,
    bucket: s3 bucket 이름,
    //key로는 함수를 줘야 합니다. 여기서, multer에서 로드하는 파일의 이름과 같은 정보를 얻을 수 있고, 콜백함수에 (null, s3에 저장할 파일 이름)을 넘겨주면 됩니다.
    key: function(req, file, cb){
        //파일 확장자 가져오기
        const filename_arr = file.originalname.split('.');
        const extend = filename_arr[filename_arr.length-1];
        //중복되지 않을만한 파일이름에 확장자를 붙여서 저장.
        cb(null, 'file'+'-'+new Date().now())+'.'+extend)
    },
    //s3에 저장되는 이미지의 접근 권한입니다.
    acl: 'public-read-write'
}

acl에 넣을수 있는 정보는 여기를 참고하시면 됩니다.

자 이제 거의 다 되었습니다.

마지막으로 이렇게 만든 미들웨어를 앞에서 만든 라우터에 추가해주기면 하면 됩니다.

...

router.post('/uploads3', upload.single("file"), (req, res) => {
    res.send('success');
})
...

그리고 Form에서 이렇게 보내주시기만 하면 됩니다.

<form action="/uploads3" method="post" id="post" enctype="multipart/form-data">
    <input name="file" type="file">
</form>


이렇게 간단하게 Node.js와 S3을 연동하는 법을 알아보았습니다! 만약 권한등의 문제가 발생한다면, 만드신 S3 버킷의 접근 권한설정등을 살펴보세요. 스토리지 자체에 외부에서 접근할 수 있는 권한을 허용하지 않았을 가능성이 높습니다.


Categories