본문 바로가기

AWS

multer-s3

multer,multer-3

nodejs 미들웨어로 S3는 Amazon Simple Storage Service로, 인터넷용 스토리지 서비스입니다. 쉽게 AWS에서 제공하는 파일 저장 공간이라고 생각하시면 됩니다. multer-s3를 사용하여 이미지 업로드 시 로컬 서버가 아닌 S3에 이미지를 업로드하게 됩니다.

설치

npm install multer multer-s3

설정

ImageUpload.js

const multer = require('multer');   
const {v4: uuid} = require('uuid')
const mime = require("mime-types");
const multerS3 = require("multer-s3") //aws
const {s3} = require("../aws")

// const storage = multer.diskStorage({ //diskStorage 사용시 파일저장과정을 제어가능
//     destination: (req,file,cb)=>cb(null, "./uploads"), 
//     filename:(req,file,cb)=>cb(null, `${uuid()}.${mime.extension(file.mimetype)}`), //uuid를 이용해 각파일당 고유이름 갖기(같은 파일을 올릴수도 있으므로)
//    })
   

const storage = multerS3({  //aws에 파일저장 (upload폴더에서 aws로 변환)
    s3,
    bucket:"image-upload2", //버켓이름,
    key:(req,file,cb)=>cb(null, `raw/${uuid()}.${mime.extension(file.mimetype)}`), //key설정 raw폴더안에 저장
});


const upload  = multer({storage , fileFilter:(req,file,cb)=>{ //multer 이용한 upload  , filter를 이용해 이미지저장
    if(['image/jpeg' , 'image/png'].includes(file.mimetype)) cb(null,true) // true = 저장
    else cb(new Error('invalid error'), false) //fasle = 저장x 
}, 
limits:{
    fileSize:1024*1024*5,  //파일 사이즈 제한

},
});   

module.exports = {upload} //미들웨어

aws 키가 노출되면 엄청난 요금이 청구될 수 있으니 주의.

사용

index.js

imageRouter.post('/',upload.single("image"),async function(req,res){    //포토번호 , 미들웨어(이미지 하나받기) ,실행함수  "image":key

    //유저권한 확인: 미들웨어 확인 , 유저정보저장 ,public유무 확인
    try{
        if(!req.user) throw new Error("권한이 없습니다")//로그인x
        const image = await new Image({
            user:{ _id:req.user.id , name:req.user.name , username:req.user.userName}, //_id : objectID  id: _id를 알아서 string으로 변환해줌 (object <->string 몽구스에서 알아서 변환해줌)
            public: req.body.public, //원래 string으로 보내지만 몽구스에서 boolean으로 바꿔줌(나중에 json으로 바꿔줘야됨)
            key: req.file.key.replace("raw/",""), // /raw를 빼고 빈열로 대체
            originalFileName: req.file.originalname
        }).save()                                   //save = 데이터베이스에 저장하는부분 // 비동기적부분 : async 사용
        res.json(image)//리턴부분
    }
    catch(err){
        res.status(400).json({message:err.message})//400 :유저잘못입력 , 500:서버오류
        console.log(err)
    }

});  
//single ->array로 바꿈 5는 최대장수

결과는 req.file, req.files에 저장된다.

 

 

 

 

 const formData = new FormData //데이터는 보통 json으로 보내주는데 이미지파일은 formdata이용
        
 formData.append("image", file)//key,value  // 여기서 key는 백엔드의 upload.single("image") 와 동일시
 formData.append("public" , isPublic)
         
         
 const res = await axios.post("/images" , formData , {  //경로,데이터,
     headers: {"Content-Type": "multipart/form-data"}, //보내는 리소스 타입
     onUploadProgress : (e) =>{   //자바스스크립트 내장함수
     setPercent(Math.round((100 * e.loaded)/e.total)); //이미지 업로드시 프로그레스바 퍼센트 업데이트
     },
  });

 

프론트단에서 input 프로퍼티
enctype="multipart/form-data"를 추가하던가,
axios에이런식으로 컨텐트타입을 설정해주어야 한다.

'AWS' 카테고리의 다른 글

S3 presignedUrl 생성 , presignedUrl이용해서 S3,DB에 이미지저장  (0) 2022.03.10
s3 deleteObject  (0) 2022.03.09
IAM 유저생성  (0) 2022.03.05
S3+CloudFront  (0) 2022.03.04
S3  (0) 2022.03.04