As i wish

[Node JS] Node 서버에서 이미지 s3로 업로드 본문

Node JS

[Node JS] Node 서버에서 이미지 s3로 업로드

어면태 2020. 1. 18. 11:25

안녕하세요. 엄티입니다.

오늘은  Node 서버에서 image url를 가지고 s3 업로드 하는 방법을 포스팅해보겠습니다.

일단 먼저 AWS 계정을 만들고, s3에 bucket을 만들어야하는데, 이는 워낙 간단하니 생략하도록 하겠습니다.

이렇게 buckt을 생성하면 됩니다.

 

저는 제가 생성한 'kjglass-images' 버킷에다가 이미지를 올릴거에요.

일단 저는 기존에 레거시 사이트에서 크롤링을 통하여 이미지 링크(image src) 를 알고 있고 이를 node 서버에 잠시 업로드 한뒤, 바로 s3에 업로드 하는 방식으로 작업을 진행하겠습니다.

1. 먼저 aws 를 프로젝트에 설치해줍니다.

$ npm i aws-sdk

2. 파일을 읽을 수 있는 모듈도 설치해줍니다.

$ npm i fs

3. aws config 를 설정해줍니다.

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

AWS.config.loadFromPath('aws.config.json');
const s3 = new AWS.S3()

저는 aws.config.json 파일을 만들었는데 여기에는 

{
    "accessKeyId": "accessKeyId",
    "secretAccessKey": "secretAccessKey",
    "region": "ap-northeast-2"
}

이렇게 생긴 json 파일이 있어야 합니다. 이는 보안상 문제가 되므로 gitignore처리를 해주셔야합니다.

이 정보는 aws console 에서 자신의 이름을 클릭 -> 내 보안 자격 증명 -> 액세스 키 -> 액세스 키 만들기 를 통해서 가져올 수 있습니다. 이 키가 있으면 누구든 접속 할 수 있기 때문에 보안에 각별히 신경 써주세요.

4. uploadImageToS3

const uploadImageToS3 = (imageUrl, fileName) => {
    return new Promise((resolve, reject) => {
        fetch(imageUrl).then((res) => {
            res.body.pipe(fs.createWriteStream('temp.jpg')).on('finish', (data) => {
                const param = {
                    Bucket: 'kjglass-images',
                    Key: fileName,
                    ACL: 'public-read',
                    Body: fs.createReadStream('temp.jpg'),
                    ContentType: 'image/jpg'
                };
                s3.upload(param, (error, data) => {
                    if (error) {
                        console.log('Upload s3 error', error);
                    }
                    console.log(data);
                });
            });
        });
    });
};

위와 같이 함수를 만들었는데, 일단 imageUrl를 가지고 fetch를 통하여 정보를 가져온뒤, 이를 fs.createWriteStream 을 통하여 서버내에 올려줍니다. (temp.jpg 로) 그 다음 이 올려진 이미지를 s3 에 업로드 하는 방식으로 구성 하였습니다.

const param = {
    Bucket: 'kjglass-images',
    Key: fileName,
    ACL: 'public-read',
    Body: fs.createReadStream('temp.jpg'),
    ContentType: 'image/jpg'
}

Bucket: 아까 만들었던 Bucket name
Key: 파일이 저장될 때 사용하는 이름, 만약 test/a.jpg라고 쓰면 Bucket 내에 test 폴더 안에 a.jpg로 저장됩니다. 그냥 b.jpg라고 쓰면 Bucket내에 b.japg로 저장되겠죠?
ACL: S3에 정의된 권한이라고 보면 됩니다.
Body: 저장되는 데이터이다. String, Buffer, Stream 이 올 수 있습니다.
ContentType: 말그대로 content-type입니다.

이렇게 param 을 만들어서 넣어주고 upload를 시키면 아주 잘 동작하는 것을 보실 수 있습니다!

 

그럼 오늘도 즐 코딩

 

* 전체 코드

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

AWS.config.loadFromPath('aws.config.json');
const s3 = new AWS.S3();

const uploadImageToS3 = (imageUrl, fileName) => {
    return new Promise((resolve, reject) => {
        fetch(imageUrl).then((res) => {
            res.body.pipe(fs.createWriteStream('temp.jpg')).on('finish', (data) => {
                const param = {
                    Bucket: 'kjglass-images',
                    Key: fileName,
                    ACL: 'public-read',
                    Body: fs.createReadStream('temp.jpg'),
                    ContentType: 'image/jpg'
                };
                s3.upload(param, (error, data) => {
                    if (error) {
                        console.log('Upload s3 error', error);
                    }
                    console.log(data);
                });
            });
        });
    });
};
Comments