[AWS] S3 연결하기 ( 이미지 업로드 )

    728x90
    반응형

     

     

    [AWS] S3 연결하기

    프로젝트를 배포하고 이미지 업로드할 때 문제가 있다.

    현재 백엔드 서버에다 이미지 올리고 있는데,

    이렇게 된다면 차후에 백엔드 서버가 스케일링 될때 그 이미지들까지 복사되어버린다.
    이미지는 하나만 있으면되는데 여러 컴퓨터에 복사해놓을 필요가 없다.
    s3가 이런 백업도 다 처리해준다. 우린 할 필요 없음
    프론트에서 이미지 올릴때 바로 s3로 보내려고 한다.

     

     

     

    AWS S3

    AWS S3 (Amazon Simple Storage Service)는 Amazon Web Services가 제공하는 객체 스토리지 서비스입니다.

    이 서비스는 인터넷을 통해 언제 어디서나 데이터를 저장하고 검색할 수 있는 확장성이 높은 클라우드 스토리지 솔루션을 제공합니다.

    S3는 특히 대규모 데이터를 저장하고 관리하기에 적합하며, 무제한의 스토리지 공간을 제공합니다.

     

    주요 특징은 다음과 같습니다:

    1. 내구성과 가용성: S3는 데이터를 자동으로 여러 물리적 위치에 복제하여, 고도의 내구성과 99.99%의 가용성을 보장합니다.
    2. 보안: 다양한 보안 기능을 제공하여 데이터를 안전하게 보호합니다. 이에는 SSL을 통한 데이터 전송 암호화, 데이터 액세스를 위한 정교한 권한 설정 등이 포함됩니다.
    3. 확장성: 사용자는 데이터 양에 관계없이 필요한 만큼 저장 공간을 사용할 수 있습니다.
    4. 비용 효율성: 사용한 만큼만 비용을 지불하는 Pay-as-you-go 모델을 채택하여, 미사용 스토리지에 대한 비용이 발생하지 않습니다.
    5. 관리 편의성: AWS 관리 콘솔, SDKs, API를 통해 S3 리소스를 쉽게 관리할 수 있습니다.

     

    사용 사례:

    • 웹사이트의 정적 자산(이미지, 스타일시트, 자바스크립트 등) 호스팅
    • 데이터 레이크로서의 사용, 빅 데이터 분석 및 보관
    • 백업 및 재해 복구 솔루션
    • 모바일, 웹 어플리케이션의 사용자 데이터 저장

    AWS S3는 간편하게 데이터를 저장하고 전 세계 어디서나 접근할 수 있는 유연한 스토리지 옵션을 제공하여,

    다양한 규모의 비즈니스 및 개인 사용자가 데이터 관리 및 배포를 효율적으로 수행할 수 있게 돕습니다.

     

     

     

    버킷 만들기

    aws에서 s3를 검색하고

    s3페이지에 들어가서 버킷 만들기를 한다.

     

     

    이후 버킷 만드는 페이지가 뜨는데

    이름을 고유한것으로 지정하고

    아래 퍼블릭 액세스 차단 설정을 체크 해제한다.

    그리고 그 아래의 경고창에 체크를 해야 다음으로 넘어갈 수 있다.

     

     

     

    버킷 설정 하기

    설정한 버킷으로 들어가서

    권한 메뉴 > 버킷 정책에 아래와 같이 작성해준다.

    남들이 이곳에 접솔할 수 있게 된다.

     

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Addperm",
                "Effect": "Allow",
                "Principal": "*",
                "Action": [
                    "s3:GetObject",
                    "s3:PutObject"
                ],
                "Resource": "arn:aws:s3:::zzimzzim-s3/*"
            }
        ]
    }

     

     

     

     

    엑세스 키 만들기

    이게 있어야 node에서 s3로의 접근권한이 주어진다.

    내 보안 자격증명 페이지 들어간다.

    아래 액세스키 섹션에서 액세스만들기

     

     

    만들기 한다음에 파일 다운로드해준다. 

    이건 노출해선 안된다. 

    노출되면 매우매우 위험하다..

     

     

     

     

     

     

    백엔드 설정

    기존에 이미지를 로컬에 올리다가.

    백엔드를 배포하고 백엔드 서버에 올렸다가

    s3에 올리려고 한다. 

     

    .env

    .env에 키 에대한 정보를 입력해준다.

    /back/.env

    COOKIE_SECRET = xxx
    DB_PASSWORD = xxx
    S3_ACCESS_KEY_ID = xxx
    S3_SECRET_ACCESS_KEY = xxx

     

    그런데 실무에서는 accesskey 방식보다 im방식을 더 쓴다고한다. 

    accesskey 방식은 권한이 강력해서 s3말고 다른데도 접근할 수 있어서 더 조심해야한다. 

    간단한만큼 보안에 취약해서 조심!

     

     

    multer-s3

    multer?

    • Express에서 파일 업로드를 처리하기 위해 사용되는 미들웨어
    • 모듈은 주로 multipart/form-data 형식을 다루며, 이는 HTML form에서 파일이나 데이터를 서버로 전송할 때 사용
    • multer은 파일인 경우 req.body.files(여러개)나 rec.body.file(한개)이 된다.
    • 파일이나 이미지가 아닌 텍스트들은 req.body 넣어준다.
    • multipart형식으로 서버에 보내려면 formData로 보내야한다.
    • multipart로 보내야 multer가 처리할 수 있다.

    이 미들웨어를 multer-s3로 바꿔준다.

     

     

    필요한 모듈 설치해준다.

    /back/package.json

    npm i multer-s3 aws-sdk
    
    // multer-s3 = multer를 통해서 s3로 올릴때 사용
    // aws-sdk = s3 접근권한 얻을 때 사용

     

     

    multer가 업로드를 알아서 해주기 때문에

    storage를 s3로 바꾸기만해주면 나머지 과정은 거의 비슷하게 됨

    /routes/post.js

    const multerS3 = require('multer-s3');
    const AWS = require('aws-sdk');
    
    AWS.config.update({
        accessKeyId: process.env.S3_ACCESS_KEY_ID,
        scretAccessKey: process.env.S3_ACCESS_KEY_ID,
        region: 'ap-northeast-2'
    });
    const upload = multer({
        storage: multerS3({
            s3: new AWS.S3(),
            bucket: 'zzimzzim-s3',
            key(req, file, cb) {
                cb(null, `original/${Date.now()}_${path.basename(file.originalname)}`)
            }
        }),
        limits: { fileSize: 20 * 1024 * 1024 }, // 20MB
    });
    
    // POST /post/images
    // 이미지 한장이면 upload.single / 없으면 upload.none / 파일 태그가 두개씩 있을때 fields
    // upload에서 이미지를 처리하고 처리된 이미지를 다음 콜백함수에서 req.files로 받는다.
    router.post("/images", isLoggedIn, upload.array("image"), (req, res, next) => {
        try {
            console.log(req.files);
            res.json(req.files.map((v) => v.location));
        } catch (error) {
            console.error(error);
            next(error);
        }
    });

     

     

    중요 에러!

    ***.env에 있는 정보들은 git에 올리지 않는다.

    그래서 비밀코드나, 중요 정보들이 서버에서 필요하게 되면 vim으로 수동으로 해서 그때그때 적용해줘야 한다.

    마찬가지로 비밀코드 ( S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY ) 는 철저하게 관리해야하기 때문에

    필요할때마다 수동으로 입력해줘야한다.

    S3 설정이 잘 못되면 missing credential 에러가 발생하는데 이를 보고 vim을 추가해주면 된다.

     

     

    ***TypeError: this.client.send is not a function

    multer-s3, aws-sdk 를 적용 후 아래와 같은 에러가 발생했다면

    두 미들웨어 간의 버전이 맞지 않는지 확인해봐야한다.

    multer-s3을 2버전대로 낮추거나 그에 맞는 aws-sdk 3버전을 찾아보고 적용하면 된다. 

     

     

     

     

    프론트 설정

    이미지를 s3에다가 올리면 s3용 이미지 주소가 따로 생긴다.

    이 주소를 프론트쪽에 적용해줘야 한다.

    이전에 백엔드 api + 이미지 경로로 지정했던 코드들을 백엔드 api부문을 제거해준다.

    s3 주소자체가 이미 경로고 이게 전달되기 때문에 백엔드 api 더해줄 필요가 없다.

     

     

     

     

     

     

     

    참조!

    https://www.inflearn.com/course/lecture?courseSlug=%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC&unitId=49080&category=questionDetail&tab=curriculum

     

    학습 페이지

     

    www.inflearn.com

     

    728x90
    반응형

    댓글