[Node.js] 이미지 업로드 기능 만들기(AWS S3 설정)

yellowbutter·2024년 6월 17일

NodeJs

목록 보기
7/8
post-thumbnail

1. aws 기본 설정

1. aws 가입

2. 검색창에 i am 이라고 검색하기

3. 사용자 만들고 정책 연결

4. s3 검색하고 확인

5. 만든 사용자 들어가서 액세스 키 만들기

6. 액세스 키와 비밀번호, ARN 보관

7. s3 검색해서 들어간 후 버킷 생성하기

  • 객체 소유권 비활성화

8. 설정


처음에는 차단 해제 시켰다가, 이후에 개발 시작되면 분홍색으로 된 것들은 체크

9. 버킷 권한 설정

  • 버킷 정책 편집에서 버킷명, ARN 등 채워넣는다.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::버킷명/*"
        },
        {
            "Sid": "2",
            "Effect": "Allow",
            "Principal": {
                "AWS": "ARN주소!!"
            },
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::버킷명/*"
        }
    ]
} 

10. cors 설정

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
] 

2. 이미지 업로드

  1. 글 작성 페이지에 이미지 input
  2. 서버는 이미지 받으면 s3에 업로드
  3. 이미지 url은 db에 글과 함께 저장
  4. 이미지가 필요하면 db에 있던 url 가져와 html에 표시

2.1. 글 작성 페이지에 input 만들기

//write.ejs
<form class="form-box" action="/add" method="POST" enctype="multipart/form-data">
    <input type="file" name="img1" accept="image/*" multiple>
</form> 

✔️ 이미지 여러장 넣을거면 multiple 붙인다.

//server.js
//upload.single : name="img1"가진 이미지 들어오면 s3에 자동 업로드 해준다.
app.post("/add", upload.single("img1"), async (요청, 응답) => {
  // 업로드 완료시 이미지 url 생성해준다. 그게 바로 요청.file이다.
  //여러장이 올때는  upload.array('img1',2) 이런식으로 적어준다.
  console.log(요청.file);
  //console.log하면 location나오는데 이거를 src에 넣으면 이미지 링크로 연결된다.
  //여기서 요청.body는 {title: '' , content: ''} 이런 형식일듯
  try {
    if (요청.body.title === "") {
      응답.send("잘못된 요청입니다.");
    } else {
      await db.collection("post").insertOne({
        title: 요청.body.title,
        content: 요청.body.content,
        img: 요청.file.location,
      });
      // 응답.send()
      응답.redirect("/list");
    }
  } catch (e) {
    console.log(e);
    응답.status(500).send("서버에러");
  }
});

✔️ enctype, type, accept
✔️ form type에 multipart/form-data라고 적어줘야
✔️ accept 속성으로 이미지파일만 선택할 수 있게 제한할 수 있는데
제한이 아니라 권장일 뿐이라파일타입을 아예 제한하고 싶으면
서버에서 확장자 검사해보는게 좋다.

2.2. 서버는 s3를 통해 이미지를 업로드 한다.

npm install multer multer-s3 @aws-sdk/client-s3 
//server.js에 추가 
const { S3Client } = require('@aws-sdk/client-s3')
const multer = require('multer')
const multerS3 = require('multer-s3')
const s3 = new S3Client({
  region : 'ap-northeast-2',
  credentials : {
      accessKeyId : 'IAM에서 발급받은 액세스키',
      secretAccessKey : 'IAM에서 발급받은 시크릿키'
  }
})

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: '버킷이름',
    key: function (요청, file, cb) {
      cb(null, Date.now().toString()) //업로드시 파일명 변경가능  
      //s3에 업로드할 이미지 파일명 작성하는 곳
      //업로드시 파일명 변경가능
      //파일명이 겹치지 않기 위해서 랜덤한 시간이나 문자를 기입하는 경우가 있음.
      //upload.single('input이름') 하면 S3에 업로드 된다
    }
  })
})
  • region : 부분은 S3 리전 설정하는 부분, 서울로 s3 셋팅해놨으면 ap-northeast-2 기입

  • 저장할 파일명도 맘대로 바꿀 수 있다.

  • 파일명을 안겹치게하려면 랜덤문자를 해싱해서 집어넣던가 아니면 현재시간을 섞거나 그래도 된다.

  • 원래 파일명은 요청.file 하면 나온다.

  • upload.single('input이름') 하면 S3에 업로드 된다

profile
기록은 희미해지지 않는다 🐾🧑‍💻

0개의 댓글