Seongwon Lim

[node.js] AWS S3에 텍스트 파일 업로드 및 다운로드 기능 구현하기 본문

Node.js

[node.js] AWS S3에 텍스트 파일 업로드 및 다운로드 기능 구현하기

limsw 2022. 5. 10. 00:42
반응형

이번 포스팅에서는 node.js 에서 AWS의 S3에 텍스트 파일을 업로드하고 업로드한 파일을 다운로드(읽기)하는 내용을 다룬다.

또한 S3 bucket은 생성된 이후를 다루기 때문에 버킷 생성에 관한 내용은 상세히 다루지 않는다.


다만, 버킷에 저장되어 있는 객체를 외부에서 접근할 수 있도록 하기 위해서는 버킷의 권한 설정이 필요하므로 버킷 생성 시 권한 설정에 대한 부분은 다룰 예정이다. 전체 공개된 버킷이 아닌 경우 외부에서 S3 Bucket에 접근할 때에는 IAM 사용자 권한이 필요하므로 IAM 사용자 생성에 관한 내용 또한 다루고자 한다.

버킷 생성 시 퍼블릭 액세스 차단 설정


위와 같이 버킷 권한을 설정하면 공개 키, 비밀 키를 이용하여 외부에서 버킷에 접근할 수 있다.


AWS IAM 사용자 추가

AWS의 IAM 서비스에서 사용자 탭을 클릭 후 사용자 추가 를 클릭한다.

사용할 사용자 이름을 정의한 뒤 AWS 자격 증명 유형 선택에서 액세스 키 - 프로그래밍 방식 액세스 를 선택한다.

권한 설정에서는 기존 정책 직접 연결 을 선택한 뒤 AmazonS3FullAccess를 선택한다.

태그, 검토 단계는 별다른 설정 없이 넘어간다.

 

위 과정을 거친 뒤 사용자를 만들면 액세스 키, 비밀 액세스 키 를 할당받는데 2개의 키는 이후 Node.js 에서 AWS S3에 접근할 때 필요하므로 복사하여 가지고 있어야 한다.


IAM의 사용자 탭으로 들어가보면 사용자가 추가된 것을 확인할 수 있다.


Node.js 환경 구성하기

  • npm init : node.js 환경 초기 세팅
  • npm i express —-save : express 모듈 설치
  • npm i aws-sdk —-save : aws 모듈 설치

또한, 이번 예제는 form-data를 이용하여 파일 업로드 기능을 구현하는 것은 아니므로 구성한 node.js 폴더에 sample.txt 파일을 미리 넣어놓은 상태에서 진행했다.

 

해당 링크에서 샘플 데이터 파일을 다운받아서 사용하였다.

파일 업로드를 위한 index.js 파일 구성

// index.js
const express = require('express');
const app = express();
const AWS = require('aws-sdk');

const s3 = AWS.S3({
    accessKeyId: 'user accessKey', // 사용자의 AccessKey
    secretAccessKey: 'user secretAccessKey' // 사용자의 secretAccessKey
});

const bucket_name = "user bucket name"; // 생성한 버킷 이름

app.get('', (req, res, next) => {
    const fileContent = fs.readFileSync('./sample.txt');

    const params = {
        Bucket: bucket_name,
        Key: 'sample.txt', // file name that you want to save in s3 bucket
        Body: fileContent
    }

    s3.upload(params, (err, data) => {
        if (err) {
            res.send(err);
        }
        else {
            res.status(201).send(data);
        }
    });
});

app.listen(3000, () => {
    console.log("starting node.js server at localhost:3000");
});

 

  • Key : 객체가 버킷에 저장될 때 사용될 이름을 정의한다.
  • Body : 해당 객체에 저장될 내용을 정의한다.

이제 node index.js 명령어를 통해 터미널에서 서버를 실행시킨 뒤 알맞은 경로로 요청을 보내면 된다.


결과 확인하기

포스트맨을 통해서 http://localhost:3000 경로로 GET 요청을 보내면 다음과 같은 결과를 얻을 수 있다.


그리고 AWS S3 콘솔로 들어가서 버킷 안의 내용을 확인해보면 업로드 시 지정한 sample.txt 이름으로 객체가 생성된 것을 확인할 수 있다.

이번 예제에서는 단순히 파일 저장을 위해서 GET 요청으로 간단하게 구현해 보았지만 실제로 서비스를 구현할 때에는 POST 요청을 통해서 body에 직접 저장 시 object 이름, 업로드 할 파일명 등을 요청하여 서비스를 구현해야 훨씬 완성도 있는 서비스를 구현할 수 있을 것이다.


파일 다운로드를 위한 index.js 수정

이번에는 위에서 정의한 index.js 파일에서 GET 요청을 통해 sample.txt 파일을 읽어보고자 한다.

 

이전에 파일을 업로드할 때 경로를 http://localhost:3000 으로 주었으므로 이번에는 http://localhost:3000/download 경로에 GET 요청을 통해 파일을 다운로드 받도록 할 것이다.

// index.js
app.get('/download', (req, res, next) => {
    const params = {
        Bucket: bucket_name,
        Key: 'sample.txt' // 버킷에서 가져올 객체 이름
    }
		// getObject를 이용하여 객체의 데이터를 가져올 수 있다.
    s3.getObject(params, (err, data) => {
        if (err) {
            res.send(err);
        }
        else {
// body에서 입력받은 값을 파일명으로 사용하여 로컬에 결과를 저장한다.
            fs.writeFileSync(req.body.filename, data.Body.toString());

            res.status(200).json({
                content: data.Body.toString()
            })
        }
    });
});

fs.writeFileSync 는 로컬에 결과를 저장하기 위해 사용한 것이다. 실제 서비스에서 결과를 저장하지 않고 데이터만 파싱하여 사용할 경우에는 res.json(...) 혹은 res.send(...) 를 사용하면 된다.

req.body undefined Error 발생 시

node.js 에서 body에 내용을 담아 요청을 보낼 때 undefined 에러가 발생하는 경우가 있다. 이 때에는

npm i body-parser —-save 를 이용해서 body-parser 모듈을 다운 받은 후 index.js 파일 상단에 아래 코드를 붙여 넣으면 해당 에러를 해결할 수 있다.

const bodyParser = require('body-parser'); 
app.use(bodyParser.urlencoded({extended:true})); 
app.use(bodyParser.json());

다운로드 결과 확인하기


이와 같은 형식으로 해당 경로에 GET 요청을 보내면 사용자의 로컬에 result.txt 이름으로 파일이 저장되는 것을 확인할 수 있을 것이다.

또한 포스트맨에서 확인해보면 아래와 같은 결과를 얻을 수 있다.

다음 포스팅에서는 node.js의 multer와 s3를 이용해서 s3에 이미지를 업로드하는 내용을 다뤄볼 것이다.

Comments