deployment/AWS

[AWS] Express + AWS3 express통해 이미지 S3에 업로드하기

hojung 2022. 7. 17.
728x90
반응형

1. 무엇을 하려하는가?

Next JS와 Express를 통해서 블로그를 만들고 있던 중 이미지는 multipart를 처리하는 미들웨어인 multer를 통해 저장하기로 하였다. 하지만 multer의 local storage를 사용하면 이미지를 저장할 때 express서버가 열려있는 나의 컴퓨터에 저장이 되어 메모리 상 문제가 생길 거 같았다. 그래서 외부 스토리지를 찾던 중 가장 좋을 거 같다고 생각한 곳이 바로 AWS의 S3이다.  S3에 이미지를 업로드하고 그 주소만을 반환하면 S3에서 이미지를 반환하여 로컬 서버에 무리를 주지 않고도 이미지를 불러올 수 있을 것이다. 

 

2. 무엇이 필요한가?

front-end에서는 딱히 필요한 것은 없다. 그저 backend가 제공하는 api를 호출해주면 된다. 

back-end에서는 라이브러리로 multer-s3와 aws-sdk가 필요하다. 

그리고 aws 계정과 s3스토리지 버킷을 퍼블릭으로 변경해주는 과정이 필요하다. 

 

3. 과정

1. back-end(expressjs)에서 multer-s3와 aws-sdk설치

npm i multer-s3 aws-sdk --save

2. aws계정 생성 

계정이 있다면 로그인을 하고 없다면 회원가입을 하면 된다. 

그 후 S3로 이동한다. 

그 후 사용할 버킷을 만들어준다. 

나는 다음과 같은 버킷을 만들어주었다. 그 후 버킷 정책을 퍼블릭으로 변경해주어야한다. 

권한

권한 부분으로 이동하면 아마 버킷 정책이라는 것이 보일 것이다. 

버킷 정책을 다음과 같이 설정하고 저장을 하면 아마 버킷을 퍼블릭으로 접근할 수 있을 것이다. 

그 후 aws-s3에 접근할 수 있는 rootkey를 발급해줄 텐데 이 과정은 구글에 검색하면 많이 나오니 생략하겠다. 

발급받으면 다음과 같이 .csv파일로 다운을 받을 수 있다. 

3.  express에서 aws config작성

import AWS from 'aws-sdk';
import multerS3 from 'multer-s3';
import { s3_access_key_id, s3_secret_access_key } from './password.js';

AWS.config.update({
	accessKeyId: s3_access_key_id,
	secretAccessKey: s3_secret_access_key,
	region: 'ap-northeast-2',
});

export const uploadS3 = multer({
	storage: multerS3({
		s3: new AWS.S3(),
		bucket: 'simbwatda',
		key(req, file, cb) {
			cb(null, `multiAlbum/${Date.now()}_${path.basename(file.originalname)}`);
		},
	}),
	limits: { fileSize: 20 * 1024 * 1024 },
});

다음과 같이 aws config를 작성해주면 된다. 저기서 access_key와 secret_access_key는 아까 다운 받은 root Key파일에 존재하는데 나는 깃허브로 코드를 관리하고 있으므로 비밀키가 유출되면 안되어 다른 파일에 비밀 키를 저장해주고 .gitignore파일에 비밀번호가 들어있는 파일을 추가해주었다. 

다음과 같이 multerS3미들웨어를 만들어 주면 multipart데이터를  s3에 저장할 수 있게 된다. 

 

4. 라우터 작성

import express from 'express';
import { uploadS3 } from '../multer.js';
export const multiAlbumRouter = express.Router();

multiAlbumRouter.post('/uploadMultiAlbumPost', isLoggedIn, uploadS3.array('multiImage'), (req, res) => {
	console.log('multiupload', req.files);
	res.json(req.files.map((y) => y.location)); // 파일 명 리턴
	//리사이징
});

다음과 같이 라우터를 작성해준 후 이미지가 S3에 잘 들어가는 지 확인해 보겠다. 

 

5. front에서 axios요청 

다음과 같이 input태그의 change 이벤트를 받아 multiAlbum/uploadMultiAlbumPost로 요청을 보냈다. 또한 이미지는 multipart 데이터이므로 FormData에 넣어서 요청을 보냈다. 

 

6. 결과

업로드한 이미지들이 잘 저장되어 있는 것을 확인할 수 있었다. 

 

728x90
반응형

댓글