일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- For
- laravel
- NCP
- Go
- fastapi
- Node
- SQL
- nodejs
- CentOS
- deep learning
- nginx
- phpredis
- Machine Learning
- javascript
- Switch
- linux
- Redux
- 블레이드 템플릿
- docker
- rabbitmq
- Babel
- python
- mariadb
- 기초 수학
- Backbone.js
- webpack
- React
- AWS
- Redis
- php
- Today
- Total
개발일기
AWS S3에 파일 업로드 본문
1. AWS S3를 활용한 이유???
개인 프로젝트를 진행하면서 Quill 에디터를 활용하여 포스팅을 할 수 있는 기능은 구현하였다. 이 기능에는 이미지를 첨부할 수 있는 기능이 있는데 이 에디터를 통하여 이미지 첨부 시, Base64타입으로 경로가 변형되어 저장이 되는 것을 확인하였다.
여기서 간단하게 Base64에 대해 설명하자면 ASCII영역의 문자들로 문자열을 바꾸는 인코딩 방식을 뜻한다. 이 방식을 통하여 인코딩하여 업로드를 진행할 시, 문자열의 길이가 상상할 수 없을 만큼 많아지는 것을 확인할 수 있다. 간단한 이미지 파일 하나를 첨부하는데 48000글자로 변형이 되어 추가되었던 것을 겪어보았다. 이러한 방식으로 이미지를 업로드하여 DB에 저장할 시, DB가 많이 아파?할 수도 있다는 것을 느꼈다. 보통 4000자 내외로 내용이 들어가는데 사진 하나 추가하여 그 기준을 가뿐히 넘겨버리는 경우는.....
그렇기 때문에 관리자 페이지에서 S3에 올려놓은 이미지들을 클라이언트 쪽에서 UUID식으로 파일명을 변경하여 업로드를 한 후, 포스팅작성시 참조하여 사용하는 방향으로 선회하였다.
2. 서버가 아닌 클라이언트 쪽에서 올리는 이유???
물론 백엔드 서버(Java, PHP, Python )등을 경유하여 파일을 업로드하여도 된다. 아주 잘된다. 하지만 이 방법의 단점으로는 동영상 등의 큰 용량의 파일을 업로드하는 경우를 예로 들 수 있다.
친구들과 함께 플레이한 게임 영상을 S3에 올려서 간직하고자 한다. 게임이 길어져서 약 50분간 녹화되었다. 용량이 대략 3GB가 되는데 이러한 큰 용량의 파일을 서버를 경유하여 업로드를 하려고 하니, 서버가 이를 버티지 못하고 녹아버렸다. 이를 방지하기 위해 클라이언트 쪽을 경유하여 파일을 업로드한다. 클라이언트를 통하여 업로드를 진행할 시, 서버에 부담을 주지 않고 업로드를 진행할 수 있다.
3. 구현 방법???
3-1. 기본 설정
필자는 프론트를 React로 구현하였고 업로드는 Node모듈인 aws-sdk를 활용하여 구현하였다.
import AWS from 'aws-sdk';
yarn add aws-sdk
npm install aws-sdk
yarn 또는 npm을 통하여 aws-sdk를 설치한 후, import에 해당하는 모듈을 선언해준다.
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region: process.env.AWS_DEFAULT_REGION,
});
선언이 후, 내 S3의 버킷관련 정보들을 포함하고 있는 객체를 하나 만들어준다.
process.env~~ 가 붙은 것은 환경변수라는 의미이다. accessKeyId, secretAcceessKey, region을 환경변수로 활용한 이유는 개발자 도구를 통하여 보여지는 자바스크립트 코드에서 내가 발급받은 고유한 S3정보를 외부에 보여주지 않기 위해서이다. 환경변수를 사용하기 위해서는
import dotenv from 'dotenv'
yarn add dotenv
npm install dotenv
dotenv모듈을 설치한 후, config.js에 해당 패키지를 사용하겠다는 선언을 진행한 후, 활용할 수 있다.
다시, 본론으로 돌아와서 발급받은 정보들을 s3라는 변수에 넣어준 후, html을 통해 input type="file"과 button type="submit"를 만들어, 업로드할 파일을 선택 후, 버튼을 클릭할 시, 해당하는 파일을 S3에 올릴 수 있는 코드를 간단하게 구현한다.
3-2. 파일 이름 지정 - UUID
위에서 말했듯이 업로드할 파일 이름은 UUID로 지정할 것이다.
UUID란 네트워크 상에서 고유성이 보장되는 id를 만들기 위한 표준 규약을 뜻한다. 고유한 이름으로 파일을 업로드해야하는 이유는 S3에 중복되는 이름을 가진 파일이 업로드되게 되면 파일이 업로드되지않는 현상이 일어나기 때문이다. 이를 방지하고자 고유한 이름을 가질 수 있게 UUID로 파일명을 지정 후, 업로드를 진행하게 되는 것이다.
import { v1, v3, v4, v5} from 'uuid';
yarn add uuid
npm install uuid
이를 통하여 uuid를 설치한 후, 업로드할 수 있다. uuid타입에는 4가지의 종류가 있다.
- v1: 타임스탬프(시간) 기준으로 생성
- v3: MD5 해시 기준으로 생성
- v4: 랜덤값을 기반으로 생성
- v5: SHA-1 해시 기준으로 생성
그 후, const uuidKey = v1(); 이런식으로 uuid값이 담긴 변수를 생성할 수 있다. 매우 쉽다.
3-3. 본격적인 구현
const uploadParams = {
Bucket: process.env.AWS_BUCKET,
Body: file,
Key: `image/${v1().toString().replace("-", "")}.${
file.type.split("/")[1]
}`,
ContentType: file.type,
ACL: "public-read",
};
3-1 에서는 S3관련 정보들을 선언했는데 요번 단락에서는 파일에 관한, 어떻게 파일을 업로드할 것인지를 명시하는 변수를 생성한다.
- Bucket : 파일을 업로드하고자 하는 버킷의 이름
- Body : 버킷에 올라갈 파일들을 뜻한다. Body안에 input type="file"을 통하여 올라간 파일을 넣어준다.
- Key : 버킷에 해당하는 파일을 올린 후, 지정해줄 이름을 뜻한다. 3-2 에서 말했듯이 이름은 고유해야한다. 이를 위해서 UUID를 활용하여 Key를 지정해주었다.
- ContentType은 업로드할 파일의 타입을 설정해준다. image/png, image/jpg 식으로 지정해서 올린다. 아무것도 지정하지 않은 상태에서 올리면 Application/octet-stream 로 지정되어 파일이 올라가게 된다.
- ACL은 권한을 뜻한다. 개인프로젝트 기능 중, 포스팅관려하여 파일을 업로드하는 것이기 때문에 public-read로 설정해놓았다. ACL을 public-read로 설정해놓으면 버킷에 권한이 없고 수정할 수 없는 권한이 없는 일반사용자들도 해당하는 파일을 확인할 수 있다.
3-4. 대망의 업로드!
S3와 파일관련 내용들을 조합하여 업로드를 진행하면 된다.
s3.putObject(uploadParams, (err, data) => {
alert("업로드 되었습니다.");
});
aws-sdk에서 제공해주는 메서드를 활용하여 업로드를 진행하면 된다. putObject가 uploadParams에 지정된 Object를 s3변수에 지정한 내용을 토대로 업로드를 진행하는 기능을 가진 메서드이다.
https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html
pubObject에는 이외에도 다양한 추가요소들이 포함되어져 있다. aws 공식문서를 통하여 확인 후, 내가 필요로 하는 기능을 좀 더 추가하여 활용할 수 있다.
https://docs.aws.amazon.com/AmazonS3/latest/API/API_Operations_Amazon_Simple_Storage_Service.html
또한 업로드 외에도 버킷을 생성하거나, 업로드된 파일들을 삭제하는 메서드들이 공식문서에 작성되어져 있다. Node외에도 다른 다양한 언어로도 작성되어져 있으니 취사선택하여 참조하면된다.
Node를 통하여 파일을 업로드하는 방법을 알아보았다. 포스팅기능 외에도 다양한 방면에서 S3에 파일을 업로드하여 활용할 수 있다. 필자처럼 기본적으로는 포스팅을 할 때, 이미지를 추가하여 포스팅을 하는 기본적인 활용법을 기반으로 좀 더 넓은 방향으로 나아갈 수 있을 거라 생각이 든다. 다음 포스팅 때는 Redis관련 포스팅을 진행하겠다. 갑자기 Redis로 확확 넘어가는 이유는 S3관련 포스팅을 하는 이유와 비슷하다. 개인프로젝트를 진행하면서 DB를 거쳐 관련 정보들을 보여주는 것보다 Redis를 캐시 서버로 활용하여 보여주는 것이 속도면에서 월등하기 때문에 이 기능을 구현하였다. Redis에는 다양한 타입들이 있기에 이를 학습하고 적용하는데 나름대로 어려움을 겪었다. 그렇기 때문에 이러한 내용도 기록해보고자한다.
'Web 서비스 > AWS' 카테고리의 다른 글
AWS - AWS CLI로 인증 정보 관리하기 (0) | 2023.01.13 |
---|---|
AWS - RDS(Relational Database Service)란? (0) | 2022.05.24 |
AWS - EC2(Elastic Compute Cloud)란? (0) | 2022.05.20 |
AWS - IAM(Identity and Access Management)란? (0) | 2022.05.20 |