Node.js로 AWS S3에 이미지 업로드하는 실전 가이드

2025. 11. 20. 15:58Web

반응형

Node.js로 AWS S3에 이미지 업로드하는 실전 가이드

multer + multer-s3 활용, 파일 크기 제한/확장자 검사까지

웹 서비스에서 이미지 업로드 기능은 이제 선택이 아니라 기본 기능에 가깝습니다.
이 글에서는 Node.js 환경에서 AWS S3(Simple Storage Service)를 이용해 이미지 업로드를 구현하는 방법을 단계별로 정리해 보겠습니다.
단순히 올리는 것에서 끝나는 것이 아니라, multer-s3를 활용해 파일 크기 제한, 확장자 검사까지 함께 처리하는 팁도 담았습니다.


AWS S3(Simple Storage Service)란?

AWS S3는 아마존에서 제공하는 객체 저장소 서비스입니다. 이미지, 동영상, 문서 파일 등 다양한 데이터를 안전하게 저장할 수 있고,
전 세계적으로 가장 많이 사용되는 클라우드 스토리지 중 하나입니다.

왜 S3를 사용할까요?

  • 비용이 비교적 저렴하고 사용량에 따라 과금되는 구조
  • 용량 제한 없이 확장 가능한 구조
  • CloudFront 같은 CDN과 연동이 쉬움
  • 버전관리, 암호화, 권한 제어 등 보안 기능 제공

정리하자면, 웹에서 이미지 파일을 안정적으로 다루고 싶다면 가장 먼저 고려해볼 만한 저장소라고 보시면 됩니다.


이미지 업로드 전에 준비해야 할 3가지

필수 준비 설명
S3 버킷 생성 이미지 파일을 저장할 공간을 AWS 콘솔에서 생성합니다.
IAM 권한 설정 Node.js 서버가 S3에 접근할 수 있도록 권한이 부여된 IAM 사용자를 만듭니다.
Access Key / Secret Key AWS SDK에서 사용할 수 있도록 액세스 키와 시크릿 키를 발급받습니다.

주의할 점은 버킷 권한을 퍼블릭으로 너무 넓게 열지 않는 것입니다.
정적 파일을 외부에서 접근할 수 있게 허용하더라도, 정말 필요한 최소 범위만 공개하는 방향으로 설정해 주세요.


Node.js에서 S3 이미지 업로드 구현하기

1. 필요한 패키지 설치

npm install multer multer-s3 aws-sdk

2. AWS SDK 및 S3 설정

.env 파일 등에 키 정보를 넣어두고, 코드에서는 환경 변수를 불러오는 방식을 추천합니다.

const AWS = require("aws-sdk");

AWS.config.update({
  accessKeyId: process.env.AWS_ACCESS_KEY,
  secretAccessKey: process.env.AWS_SECRET_KEY,
  region: "ap-northeast-2", // 한국(서울) 리전
});

const s3 = new AWS.S3();

3. multer-s3로 스토리지 엔진 설정

multer와 multer-s3를 이용해 업로드된 파일이 바로 S3 버킷으로 올라가도록 설정합니다.

const multer = require("multer");
const multerS3 = require("multer-s3");

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "YOUR_BUCKET_NAME", // 본인 버킷 이름
    acl: "public-read",         // 업로드된 파일을 공개 URL로 접근 가능하게
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: (req, file, cb) => {
      const fileName = `images/${Date.now()}_${file.originalname}`;
      cb(null, fileName);
    },
  }),
});

위 설정까지 하면 기본적인 S3 이미지 업로드는 동작합니다.
하지만 실제 서비스에서는 파일 크기와 확장자 제한이 거의 필수라고 볼 수 있습니다.


실무 팁: 파일 확장자 & 크기 제한하기

이미지 업로드 기능이 있다고 해서 아무 파일이나 다 받아서는 안 됩니다.
악성 스크립트나 서버 저장 공간을 과도하게 사용하게 만드는 파일 업로드를 막기 위해 다음 옵션들을 함께 설정해 주세요.

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "YOUR_BUCKET_NAME",
    acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: (req, file, cb) => {
      const fileName = `images/${Date.now()}_${file.originalname}`;
      cb(null, fileName);
    },
  }),
  limits: {
    fileSize: 5 * 1024 * 1024, // 5MB 제한
  },
  fileFilter: (req, file, cb) => {
    const allowed = ["image/jpeg", "image/png", "image/jpg"];
    if (allowed.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error("올바르지 않은 이미지 형식입니다. (jpg, jpeg, png만 허용)"));
    }
  },
});
  • 파일 크기 제한: 예제에서는 5MB로 제한
  • 허용 MIME 타입: image/jpeg, image/jpg, image/png
  • GIF, EXE, ZIP 파일 등은 보안과 용량 관리를 위해 업로드를 막는 것을 권장

라우터에 업로드 기능 연결하기

Express 기준으로, 단일 파일 업로드를 처리하는 기본 예시는 다음과 같습니다.

const express = require("express");
const router = express.Router();

// "image"는 클라이언트에서 보내는 form-data 필드 이름과 같아야 합니다.
router.post("/upload", upload.single("image"), (req, res) => {
  // multer-s3를 통해 업로드가 성공하면 req.file에 정보가 들어옵니다.
  res.json({
    success: true,
    imageUrl: req.file.location, // 업로드된 S3 이미지 URL
  });
});

module.exports = router;

프론트엔드에서는 form-data 형식으로 image 필드에 파일을 담아 이 라우터로 전송하면,
S3에 업로드된 후 공개 URL(imageUrl)을 응답으로 받아 사용할 수 있습니다.


정리: 지금 프로젝트에 바로 적용해 보세요

AWS S3를 이용하면 서버 디스크 용량을 크게 신경 쓰지 않고도 안정적인 이미지 업로드 시스템을 구성할 수 있습니다.
이번 글에서는

  • AWS S3 버킷과 IAM 계정 준비
  • Node.js + AWS SDK 기본 설정
  • multer-s3를 활용한 이미지 업로드 구현
  • 파일 크기 및 확장자 제한을 통한 기본적인 보안 강화

까지 한 번에 정리해 보았습니다.

이제 사용 중인 프로젝트의 업로드 로직에 한 단계씩 적용해 보세요.
직접 적용해 보면서 오류나 궁금한 점이 생기면, 그 부분을 정리해서 다시 한 번 개선하는 식으로
“내 서비스에 맞는 업로드 구조”를 만들어 가는 것이 중요합니다.

다음에는 CloudFront와 연동해서 이미지 로딩 속도를 최적화하는 방법이나,
폴더 구조 및 권한 전략을 어떻게 가져가면 좋은지에 대해서도 따로 정리해 볼 예정입니다.

궁금한 점이나 같이 다뤄줬으면 하는 내용이 있다면 댓글로 편하게 남겨 주세요 :)

 

반응형