node와 s3를 연동하면서 잘 되지 않았던 부분들을 정리하고자 글로 정리한다.
이는 세가지로 정리할 수 있다. s3연동하는 js하나, s3를 연동하는 js를 미들웨어로 넣어주어 사용하는 라우트 하나, 이에 대한 결과를 보여주는 컨트롤러로 이루어져 있다.
모듈 설치
npm install multer multer-s3 aws-sdk
위의 모듈은 s3와 node를 연동할 때 필요한 모듈이다. 이를 설치하고 난 후에 설치된 모듈의 버전을 확인해야 한다. 모듈과 관련하여 오류가 발생하였었다. 아래의 글을 한번 살펴보고 나서 이 글을 정독하거나 하면서 오류나는 부분들은 아래를 참고하면 좋다.
2023.02.08 - [Error] - [Error] this.client.send is not a function(node와 s3관련 오류 모음)
front 코드
const requestImg = async (event) => {
let formData = new FormData();
formData.append('image', event.target.files[0]);
try {
const imageRes = await axios.post(`localhost:4000/image`, formData);
} catch (error) {
console.log(error);
alert('server error');
}
};
return (
<Wrap>
<div id='imageEdit'>
<input
type='file'
id='image_uploads'
name='image'
accept='image/*'
onChange={requestImg}
></input>
</div>
</Wrap>
);
핸들러를 작성하여 사진 업로드를 하면 s3에 저장되게 한다. event.target.files[0]를 콘솔에 찍어보면 아래와 같이 정보가 나온다. 이를 formdata를 만들어서 넣어주어 axios를 이용하여 백엔드로 같이 넘겨주어 결과값을 받는다. 에러가 나오면 그에 대한 에러를 고치면 된다. 아래의 사진은 file에 대한 정보를 알려주는 것이다.
s3 객체 생성
// config/s3/s3
const multer = require('multer');
const multerS3 = require('multer-s3');
const AWS = require('aws-sdk');
require("dotenv").config();
const s3 = new AWS.S3({
accessKeyId: process.env.AWS_ACCESS_KEY,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
region : process.env.REGION_NAME
});
const upload = multer({
storage: multerS3({
s3: s3,
bucket: 'mall-product-image',
acl: 'public-read-write',
contentType: multerS3.AUTO_CONTENT_TYPE,
key: function (req, file, callback) {
callback(null, `image/${Date.now()}_${(Math.floor(Math.random() * 1e+8)+1)}`);
},
}),
});
module.exports = upload;
- s3 : 위에서 생성한 S3 객체를 생성한다. accessKeyId와 secretAccessKey는 아마존 IAM에 사용자를 지정해야 한다.
https://uhee-12.tistory.com/42
화자가 정리한 글이므로 이 글을 보고 사용자를 정의하면 된다.
- accessKeyId와 secretAccessKey 값은 외부로 노출되면 안되기 때문에 git에 업로드시 별도 파일(config, env 등)을 생성해서 gitignore 설정해야 한다.
- acl : 파일 엑세스 권한이다. 이에 대한 글도 모듈 설치에 덧붙여둔 사이트를 통해 확인할 수 있다.
- private : default, 버킷 소유자만 읽기/쓰기 가능
- public-read : 읽기만 가능, 쓰기 불가능
- public-read-write : 읽기/쓰기 모두 가능
- bucket : 버킷 이름이다. s3에 생성해둔 버킷이름을 넣는다.
- key : 파일명을 의미한다. 이것은 s3의 버킷에 들어가 어떠한 파일명으로 작성되는지에 대해 설정하는 값이다.
- 서버에 파일을 저장하는 방법→ 위는 서버에 파일을 저장하는 방법이다.
- const uploader = multer({ storage: multer.diskStorage({ destination(req, file, cb) { cb(null, __dirname + "/upload/"); }, filename(req, file, cb) { const ext = path.extname(file.originalname); cb(null, "file_" + Date.now() + ext); }, }), limits: { fileSize: 5 * 1024 * 1024 }, });
router 코드
// router/admin.js
const express = require("express");
const router = express.Router();
require("dotenv").config();
const upload = require("../config/s3/s3");
const { postit } = require("../controller/ticket");
router.post("/register", upload.single("image"), postit);
module.exports = router;
백엔드에서 실행되는 코드이다. 그리고 upload코드를 실행하여 이미지를 하나 넣는다. 위의 s3객체 생성한 코드가 미들웨어로 실행되고, 이 코드가 실행되고 나서 controller코드가 실행된다.
위의 upload.single코드는 말 그대로 이미지를 하나만 넣는다는 말이다. 복수개의 이미지를 넣을려면 아래와 같은 코드를 작성해주면 된다.
upload.array('파일명', 최대 파일 개수) -> req.files
upload.field('[{ name : '파일명' }, { name : '파일명' }, { name : '파일명' } .....]')
controlller 코드
// controller/ticket
exports.postit = async (req, res) => {
const imageURL = req.file;
console.log('req.file :: ',imageURL);
res.status(200).json({ img: req.file });
};
s3와 node를 연동시켜 이미지가 업로드되고, 이를 컨트롤러에서 req.file를 사용하여 그의 정보를 받아온다. req.file.location을 쓰면 s3의 주소를 받아온다. 주소창에 이 주소를 넣으면 이미지를 볼 수 있다. 그리고 res.status(200).json을 프론트를 보내어 잘 받아와짐을 알려준다.
주소창에 s3주소를 치면 이미지가 잘나온다.
express에서도 잘 받아와지는 것을 확인할 수 있다.
아래의 사이트를 참고하여 글을 작성하였습니다.
https://jane-aeiou.tistory.com/85?category=1018076