ABOUT ME

chanho Yoon
chyoon0512@gmail.com


깃허브


블로그 이사!

이 블로그로 이사했어요!!


Today
-
Yesterday
-
Total
-
  • Node.Js에서 AWS S3버킷에 파일 업로드 및 삭제
    Programming/NodeJS 2020. 3. 19. 02:32
    반응형

    AWS S3란?

    • Simple Storage Service의 약자로 간단히 "저장서비스"라고 부를 수 있다.

    • AWS라는 클라우드 서비스를 하나의 컴퓨터라고 했을 때 S3는 저장장치라고 할 수 있다.

    • HTTPS 형태의 API로 데이터를 저장하거나 추출하게 해주는 웹서비스 ( S3에 파일 업로드시 해당 파일에 키 값, 객체 URL이 부여된다)

    AWS S3의 구성요소

    • 버킷 : 하나의 프로젝트를 하나의 버킷이라고 생각하면 된다.

    • 폴더 : 버킷 내부에는 폴더가 존재하고 , 그 폴더 안에 파일(오브젝트)가 있다.

    • 오브젝트 : 폴더 내부에 존재하고 파일 및 파일에 설정된 내용

    AWS S3 Class 

    https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObject-property
     

    Class: AWS.S3 — AWS SDK for JavaScript

    Class: AWS.S3 Inherits: AWS.Service Object AWS.Service AWS.S3 show all Identifier: s3 API Version: 2006-03-01 Defined in: (unknown) Overview Constructs a service interface object. Each API operation is exposed as a function on service. Service Description

    docs.aws.amazon.com

    주의사항

    form(action="", method="post", enctype="multipart/form-data")

    form 속성으로 enctype="multipart/form-data" 를 꼭 포함시켜줘야 한다


    간단한 이용 순서

    AWS S3 를 사용하기 위해선 당연히 AWS에 회원가입을 해야하고 처음 회원가입시 12개월 프리티어라고 무료로 서비스를 제공해준다. ( 단 제한된 사용량을 초과했을 시에 과금이 적용됨 , 12개월 무료기간이 지나도 마찬가지 )

     

    회원가입을 했다면 IAM에서 사용자를 추가 하고 KEY와 PRIVATE_KEY를 발급받는다.

     

    그리고 S3 서비스에 들어가 버킷을 생성한다. 

     

    절대로 유저 KEY 값과 PRIVATE_KEY값이 깃허브나 외부로 업로드하는 일을 하면 안됨. 깃 커밋하기 전에 한 번더 확인할 것 .gitignore가 잘 됐나 안됐나

     


    공식 문서

    s3 버킷에 있는 오브젝트 삭제 / s3.deleteObject 

    \https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#deleteObject-property


    multerS3를 이용한 업로드

    https://www.npmjs.com/package/multer-s3

    multerS3 acl option : https://www.npmjs.com/package/multer-s3



    코드의 일부분만 작성한걸로 환경이 저와 같지 않으므로 복붙 하시면 안됩니다.

    npm install aws-sdk //AWS에서 제공하는 Node.js JavaScript용 AWS SDK
    npm install multer-s3 // 파일 업로드의 위치를 s3의 버킷으로 보냄
    import multer from 'multer'
    import multerS3 from 'multer-s3'
    import aws from 'aws-sdk'
    import routes from '../routes'
    import Video from '../models/Video' // db 비디오 모델
    
    //aws.S3 객체를 생성하고 s3에 담음 
    const s3 = new aws.S3({
      accessKeyId: process.env.AWS_KEY,   // user 만들면서 지급받은 키값
      secretAccessKey: process.env.AWS_PRIVATE_KEY,
      region: 'ap-northeast-2'
    })
    
    // upload video file
    const multerVideo = multer({
      storage: multerS3({
        s3: s3,   // s3만 써도 됩니다.
        acl: 'public-read',
        bucket: '버킷이름/video'
      })
    })
    
    // delete video file
    // 미들웨어이기 떄문에 nodeJs exporess next 함수 포함
    export const awsDeleteVideo = async (req, res, next) => {
      const {
        params: { id }
      } = req
      const video = await Video.findById(id)  // 현재 URL에 전달된 id값을 받아서 db찾음
      const url = video.fileUrl.split('/')    // video에 저장된 fileUrl을 가져옴
      const delFileName = url[url.length - 1]  // 버킷에 저장된 객체 URL만 가져옴
      const params = {
        Bucket: '버킷이름/video',
        Key: delFileName
      }
      s3.deleteObject(params, function(err, data) {
        if (err) {
          console.log('aws video delete error')
          console.log(err, err.stack)
          res.redirect(routes.home)
        } else {
          console.log('aws video delete success' + data)
        }
      })
      next()
    }
    
    export const uploadVideo = multerVideo.single('form name') 

    위와같이 form에서 파일을 받아와 s3에 업로드 하게 되면 multer는 파일(비디오,이미지)은 제외한 나머지 데이터는 req안에 들어가게 되고 이후 파일을 처리하는 컨트롤러에서 req.file 을 받아와 해당하는 file의 name, location등을 받아와 데이터베이스에 이미지 URL등을 아래와 같이 처리할 수 있게 된다.

    // 비디오 컨트롤러, videoController.js 
    export const postUpload = async (req, res) => {
      const {
        body: { title, description },
        file: { location }
      } = req
      const newVideo = await Video.create({
        fileUrl: location, // s3에 업로르 된 파일의 URL 
        title,             // form에서 submit한 name="title"
        description,       // 마찬가지로 name="description"
        creator: req.user.id  // 현재 로그인한 사용자의 ID
      })
      req.flash('success', '업로드 성공')
      //새로운 비디오 생성 후 로그인된 유저스키마 videos에 새롭게 등록되는 비디오의 id를 저장
      req.user.videos.push(newVideo.id)
      req.user.save()
      res.redirect(routes.videoDetail(newVideo.id))
    }

     

    순서

    • 파일(이미지,비디오) form에서 post로 submit =>  라우터에서 경로 찾아감 => uploadVideo(미들웨어) 실행 및 파일 업로드 처리  => uploadVideo에서 req반환 ( 파일 data ) => 컨트롤러에서 받아서 데이터베이스에 등록

    videoRouter.post(routes.upload, uploadVideo(multer 미들웨어), postUpload)

    궁금증

    uploadVideo는 미들웨어인데 next가 없는데요?? - multer 자체가 미들웨어 

     

     

    댓글

Designed by Tistory.