AWS S3 (작은 과제형 프로젝트)

민근·2024년 10월 22일
0
  • 벨로그에 썼던 다른 글들과 마찬가지로 공부하고 개발하며 메모장에 적듯이 적은 내용이기 때문에 틀린 내용이 있을 수 있고, 여기 적힌 내용들이 전부는 아니라는 점

S3 (Simple Storage Service)

: 데이터 저장 공간

기본적인 정보

  • Buckets : 데이터 저장하는 최상위 폴더 형태의 컨테이너
    S3에 저장되는 파일들을 '객체'라 부르고 모든 객체는 '키(디렉토리)'로 식별
    (ec2의 인스턴스와 비슷한 포지션인듯)
    • 버킷 이름 : 소문자, 숫자, 점( . ), 하이픈( - )만 사용가능, 최소 3글자 최대 63글자,
      문자or숫자로 시작과 끝을 내야함,
      대문자, 언더스코어, IP주소 형식 금지
  • Bucket Policy : I AM과 유사, JSON 형식의 문서
    버킷 내 모든 객체의 엑세스 제어 가능하며 특정 객체, 객체 그룹의 엑세스 제어도 가능
    • 엑세스 허용 IP 주소 또는 범위 지정 가능
    • 엑세스 가능 리소스 범위 제한 가능
    • 암호화된 연결을 사용하도록 강제 가능
    • 퍼블릭 액세스 차단을 하면 policy로 제어하기전에 막아버림(이중보안)
    • 차단 해제후 편집에 들어가서 json형식의 policy를 설정 가능
    • 간편하게 설정하고 싶다면 우측 상단의 생성기(generator)를 통해 설정 가능
  • ARN : AWS에서 사용하는 고유 식별자, 모든 리소스에 대한 고유한 식별자 역할을 함
    • ex1 : arn:aws:s3: : :my-bucket/
      ex2 : arn:aws:ec2:us-east-1:123456789012:vpc/vpc-0e1234a1234EXAMPLE
      • arn : AWS 리소스 이름을 가리킴
      • aws : 리소스가 AWS에서 호스팅된다는 것을 나타냄
      • service : AWS의 서비스 이름(ec2, s3 등)
      • region : AWS 리전 이름(us-east-1, ap-northeast-2 등)
      • account-id : AWS 계정 ID
      • resource-id : 해당 리소스의 고유 식별자(s3 버킷 이름 등)
      • s3를 쓰는 예시에선 region, account id가 빠지고 바로 resource id만 씀

백엔드에서의 사용법 ( JavaScript, Express.Js 환경 )

  1. ACCESS KEY 발급 (참고했던 블로그)
  2. AWS SDK, Multer 설치
npx yarn add @aws-sdk/client-s3 multer-s3 @aws-sdk/lib-storage
  1. 설정 파일 작성(미들웨어 혹은 그것을 만들기 위한 설정파일)
    • js 파일 작성 (s3(설정 파일)와 multer를 각각 다른 파일에 둘수도 있고 한파일에 작성할수도 있는듯)
  • s3 발사대(?) 설정(노드 메일러의 트랜스포터 느낌, s3로 파일을 보낼때 필요한 기본 정보)
dotenv.config();

const s3 = new S3Client({   // S3Client 객체를 생성하고 S3에 접근하는데 사용
  region: process.env.REGION,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY,
    secretAccessKey: process.env.SECRET_ACCESS_KEY, 
  },
})
  • multer 설정 (파일 업로드를 처리하기 위한 미들웨어)
const multerUpload = multer({
  dest: tmpdir() // tmpdir() : 운영 체제의 임시 디렉토리 경로 반환
})

사용된 코드외에

multer.diskStorage({ destination : ...)} // 파일 저장 방식 정의
multer({ limits: { fileSize: 1 * 1024 * 1024 }  }) // 파일 크기 제한 설정
fileFilter = (req, res, cb) => { ... } const multerUpload = multer({fileFilter}) // 파일 형식 필터링

등이 있다고 한다.

4. 설정 파일 기반으로 미들웨어 작성

const upload = async (req, res, next) => {
    multerUpload.single('image')(req, res, async (error) => {
        if (error) {
            return res.status(500).json({ message: error.message })
        }

        if (req.file) {
            const fileStream = fs.createReadStream(req.file.path) // 파일의 성공적인 처리시, 파일을 읽는 스트림 생성

            const uploader = new Upload({   // 파일을 S3에 업로드
            client: s3,
            params: {
            Bucket: process.env.BUCKET_NAME,
            Key: req.file.originalname,
            Body: fileStream,
            ContentType: req.file.mimetype,
            }
            })
            try {
                await uploader.done()
                next()
            } catch (error) {
                return res.status(500).json({ message: error.message })
            }
        } else {
            next()  
        }
    })  
}
  • .single(fieldname) 외에도
.array(fieldname, maxCount)	: 여러 파일 업로드
ex) multerUpload.array('images', 10)	// 최대 10개 파일
.fields(fields) : 필드 이름을 다르게 해서 여러 파일 업로드
ex) multerUpload.fields([{ name : 'image1' } , { name : 'image2' }])

등이 있다고 한다.

  • Etc..
    • fs 모듈 : node.js의 파일 시스템 모듈
      파일을 읽고 쓰는 작업을 가능하게 해줌
      해당 코드에선 .createReadStream() 을 사용해서 파일을 스트림으로 읽고 s3에 업로드하는 용도로 쓰임. 스트림 사용시 메모리 사용량을 줄이고 대용량 파일의 효율적인 처리가 가능하다고 한다.
    • new Upload 속 params 옵션 안의키 값들
      필수 키 값 :
      - Bucket : 업로드할 파일이 향할 s3의 버킷 이름
      - Key : s3에서 파일 경로 및 이름
      - Body : 업로드할 파일의 내용(stream, buffer 등)
      - ContentType : 파일의 MIME 타입
      추가 선택 키 값 :
      - ACL : 파일의 접근 제어 목록 설정(ex : 'public-read')
      - Metadata : 추가적인 메타데이터 설정
      - ContentLength : 파일의 크기 설정
      - CacheControl : 캐시 제어에 대한 정보 설정
      등이 있다고 한다.
import { S3Client } from "@aws-sdk/client-s3"
import { Upload } from "@aws-sdk/lib-storage"
import multer from "multer"
import { tmpdir } from "os"
import dotenv from "dotenv"
import fs from "fs"

dotenv.config();

const s3 = new S3Client({   // S3Client 객체를 생성하고 S3에 접근하는데 사용
  region: process.env.REGION,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY,
    secretAccessKey: process.env.SECRET_ACCESS_KEY, 
  },
})

// 멀터 미들웨어를 설정하고 파일을 디렉토리에 저장
const multerUpload = multer({
  dest: tmpdir() // tmpdir() : 운영 체제의 임시 디렉토리 경로 반환
})

const upload = async (req, res, next) => {
    multerUpload.single('image')(req, res, async (error) => {
        if (error) {
            return res.status(500).json({ message: error.message })
        }

        if (req.file) {
            const fileStream = fs.createReadStream(req.file.path) // 파일의 성공적인 처리시, 파일을 읽는 스트림 생성

            const uploader = new Upload({   // 파일을 S3에 업로드
            client: s3,
            params: {
            Bucket: process.env.BUCKET_NAME,
            Key: req.file.originalname,
            Body: fileStream,
            ContentType: req.file.mimetype,
            }
            })
            try {
                await uploader.done()
                next()
            } catch (error) {
                return res.status(500).json({ message: error.message })
            }
        } else {
            next()  
        }
    })  
}

export { upload }
profile
이전에 썼던 일기 형식의 블로그 -> https://blog.naver.com/mgeun97

0개의 댓글

관련 채용 정보