티스토리 뷰
게시판이라 하면 일반적으로 제목과 내용 이미지 등 최소한의 필요한 것이 있습니다.
그래서 이전에 AWS에 대해서 공부했지만, 아직 이해하지 못하는 과정도 많았고 오류도 있어 그 부분을 이제 겨우 해결을 해서 정리도 할 겸 내용을 쓰게 되었습니다.
일단 필자가 개발에 사용하고 있는 것은 프론트에서는 리액트입니다. 그리고 벡엔드는 노드에서 몽고 디비를 현내 사용 중에 있습니다.
위 구조를 참고로 아래 코드를 참고해주시기 바랍니다.
먼저 이미지 업로드하는 API를 만들기 위해서는 몇가지 라이브러리를 설치해야 합니다.
npm i aws-sdk dotenv multer multer-s3
1) aws-sdk
먼저 SDK는 Software Development Kit의 약자로 특정한 소프트웨어나 플랫폼을 이용해서 소프트웨어를 개발할 때 어플을 돕는 개발도구의 집합입니다. 따라서 aws-sdk는 AWS에서 개발하여 제공한 것으로 개발에 활용할 수 있도록 제공되는 도구들의 집합을 의미한다.
2) dotenv
환경변수를 .env 파일에 저장하여 서버가 구동될 때 이 파일을 읽어 해당 값을 환경변수로 설정해 주는 역할입니다.
3) multer
파일 업로드를 위해 사용되는 multipart/form-data를 다루기 위한 NodeJS의 미들웨어입니다. Multer은 단일 및 다중 파일 업로드 모두를 지원해주기 때문에 노드에서 파일 업로드 기능을 구현할 때 많이 사용됩니다.
4) multer-s3
S3 전용 파일 업로드 라이브러리 입니다.
여기서 주의할 점!
저번에 필자가 S3 업로드 기능을 하면서 여러 에러를 만났는데, 꼭 aws-sdk와 multer-s3의 버전을 확인하시기 바랍니다. 2 버전의 aws-sdk는 multer-s3 또한 2.x.x로 설치해야 합니다.(제가 이게 원인인 줄 모르고 계속 헛짓거리를 했습니다.)
최근 업데이트가 된 것이 일부가 있어 현재 두 라이브러리의 버전이 다릅니다. 이점 주의하고 하시면 문제없이 할 수 있습니다.
지금 확인해보니... multer-s3에 설명서에 있네요...
난 무엇을 위한 삽질이었는가...
이전에 버킷을 만들었다면, 버킷의 이름과 REGION 액새스키, 시크릿 액세스 키값을. env에 저장을 합니다.
AWS_BUCKET_NAME = ''
AWS_BUCKET_REGION = ''
AWS_ACCESS_KEY = ''
AWS_SECRET_ACCESS_KEY = ''
환경변수에 쓰이는 변수명은 각자 프로젝트에 맞게 변경해서 업데이트를 해주시면 됩니다. 그대로 사용 시 복사를 하고 홑 따옴표 안에 해당하는 값을 입력합니다.
이미지 업로드를 위한 코드 작성을 위해 새로운 파일을 만들어 줍니다. 경로는 각자 원하는 위치에 하시면 될 것 같아요.
필자는 이게 config, middleware, model, router 등 구분을 어디에 해야 할지 솔직히 잘 모르겠습니다. 해당 이미지 업로드 코드를 블로그 올려주신 분들 보면 경로가 엄청 다양하더라고요. 심지어 컨트롤러까지 세분화가 되어있어 아직은 잘 모르겠습니다.
const AWS = require('aws-sdk')
const multer = require('multer')
const multerS3 = require('multer-s3')
require('dotenv').config()
const bucketName = process.env.AWS_BUCKET_NAME
const region = process.env.AWS_BUCKET_REGION
const accessKeyId = process.env.AWS_ACCESS_KEY
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY
const s3 = new AWS.S3({
region,
accessKeyId,
secretAccessKey,
})
const uploadFile = multer({
storage: multerS3({
s3: s3,
bucket: bucketName + '/boards',
acl: 'public-read-write',
contentType: multerS3.AUTO_CONTENT_TYPE,
key: function (req, file, cb) {
cb(null, `${Date.now()}_${file.originalname}`)
},
}),
limits: { fileSize: 1000 * 1000 * 10 }, // 약 10메가바이트
}).single('image')
module.exports = uploadFile
1) bucket : 버킷 이름을 작성합니다. 버킷 이름 + /name을 할 경우, 버킷에 해당하는 name의 폴더가 생성이 되며 그 안에 이미지를 저장할 수 있습니다.
2) acl : 파일에 대한 액세스 제어로, 게시판에 읽고 쓰기 등 권한을 위해 선택하게 되었는데 이게 맞겠지요? 일반적으로 권장하지 않는다고는 적혀 있습니다.
3) contentType : 콘텐츠 유형을 설정하는 것으로 기본적으로 application/octet-stream으로 설정이 됩니다. 만약 자동으로 설정을 하고 싶다면 multerS3.AUTO_CONTENT_TYPE으로 설정을 하면 됩니다.
4) key : 파일 이름을 설정합니다. 함수에서 req는 솔직히 많은 정보를 가지고 와서 언제 저걸 활용할지는 모르겠습니다. file은 클라이언트에서 파일 정보를 가지고 오는데 파일에서 오는 정보는 아래와 같습니다.
{
fieldname: 'image',
originalname: '02.jpg',
encoding: '7bit',
mimetype: 'image/jpeg'
}
이미지를 업로드하면 바로 저장이 되면서 위 정보를 줍니다. 그래서 cb에 null과 내가 어떤 방식으로 저장할지에 대한 이름 규칙을 적습니다. 근데 저 null에 대해 아시는 분이 계실까요?? 그럼 원하는 파일명으로 수정해서 업로드가 가능합니다.
다음으로는 API인 라우터를 만들어 줍니다.
// Router > boards.js
const express = require('express')
const router = express.Router()
const uploadFile = require('../s3')
router.post('/image/upload', uploadFile, (req, res) => {
res.status(200).json({ success: true, imageURL: req.file.key })
})
라우터 코드는 조금 단순하죠?
일단 POST를 통해 내가 원하는 url 경로를 적어주고, 우리가 위에서 만들어준 s3코드를 불러옵니다. 거기서 성공 시 해당하는 URL코드의 키값을 받아오면 좀 전에 네이밍 규칙에 맞게 저장된 키값만 받습니다. 물론 키 말고 URL전체를 저장해서 가져올 수 있습니다.
req.file.location을 입력하면 URL 전체를 가져올 수 있습니다. 하지만 반복되는 코드가 될 것 같아서 필자는 클라이언트에서 환경변수를 만들어서 뒷부분 key값만 디비에 저장을 하게 되었습니다.
이렇게까지 하면 이미지를 업로드하는 API를 생성하게 되었습니다.
사실 다들 쉽게 쉽게 했는데 어째서 필자는 이걸 2주 동안이나 고생고생을 했는지
진짜 한심스럽기도 하지만, 포기하지 않고 계속 오류를 찾아 원인을 찾았습니다.
알고 보니 원인은 버전 문제로 단순했다는 슬픈 현실
이럴 때 보면 허탈하기도 하지만, 해결했다는 기쁨도 없지 않습니다.
그리고 또 생기는 숙제들
이해가 가지 않는다고 포기하지는 않지만, 나중에 다시 돌아보면 이 코드의 의미를 알기를 바라면서
오늘도 이 글을 마칩니다.
끝까지 긴 글을 읽어주셔서 감사합니다.
PS. 저의 궁금증을 해결해주실 분이 계실까요?
아직까지 풀리지 않는 의문점
1) multer과 multer-s3 코드 차이는 무엇일까?
- 이 부분은 여유될 때 한번 찾아서 비교해봐야겠네요. 다행히도 multer만으로도 이미지 업로드 코드를 적어주신 분을 찾았습니다.
2) multer-s3에서 이름 규칙을 정할 때 callback함수에 넣는 null은 무엇일까?
애초에 아무 기능이 없으면 null이 있지 않을 텐데, 설명서에 있을까요? 제가 못 찾은 걸까요?
'Back-End > Node' 카테고리의 다른 글
NVM을 Windows에 설치하기 (0) | 2023.02.11 |
---|---|
npm 설치시 알아두면 좋은 명령어 (0) | 2022.09.17 |
node mongodb s3 imageUpload Error (0) | 2022.07.09 |
Library : 노드 라이브러리 bcrypt로 비밀번호 암호화하기 (2) | 2022.05.14 |
mongoDB : Databases 이름 변경하기 (0) | 2022.04.16 |
- Total
- Today
- Yesterday
- Switch
- 리액트
- 코딩테스트
- 리액트 썸네일
- node-sass
- programmers
- array
- javascript
- 리액트 유튜브
- CSS
- java
- redux
- Coding Test
- mongodb
- Visual Studio Code
- 자바스크립트
- Git
- 리덕스
- 배열
- 파이썬
- 함수
- node
- 노드
- 프로그래머스
- node.js
- 뷰
- 재공부
- github
- react
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |