S3 사진 업로드 (React, Node.js)

박재현·2022년 4월 22일
2
post-custom-banner

1. AWS 버킷 생성

  • 순서대로 생성 해 준 후, 다른 곳에서도 이미지 파일에 접근할 수 있도록 권한을 수정해주어야 한다.

💡 퍼블릭 엑세스

💡 버킷 정책

  • 다음과 같이 설정 후 생성된 정책을 복사해 붙여넣으면 된다
  • Actions 의 경우 GetObject 를 선택

    🔥 다만 주의해야 할 것!
    "Resource": "arn:aws:s3:::버킷이름/*" 다음과 같이 버킷이름 뒤에/*를 꼭 붙여주어야 에러가 안난다
    나는 이거때문에 정책을 저장했을 때 계속 에러가 났다;;

2.1) React 코드

  • 간단하게 서버로 이미지 업로드를 요청하고 응답으로 받아온 이미지 파일 위치를 img src에 넣어 이미지가 나타나게 하는 코드를 작성했다.
import { useState } from 'react';
import styled from "styled-components";
import axios from 'axios';

const ImgPreview = styled.img`
  border-style: solid;
  border-color: black;
  width: 250px;
  height: 250px;
  margin: 30px;
  position: absolute;
  left: 41%;
  right: 50%;
`;

const UploadImage = styled.input`
  height: 30px;
  position: absolute;
  left: 50%;
  right: 30%;
  margin-top: 300px;
`

const ViewImage = styled.button`
  height: 30px;
  position: absolute;
  left: 50%;
  right: 35%;
  margin-top: 350px;
`;

export default function Main() {


  const [img, setImg] = useState('')

  const formSubmit = (e) => {
    const img = e.target.files[0];
    const formData = new FormData();
    formData.append('file', img);

     axios.post("이미지 요청 주소", formData).then(res => {
      setImg(res.data.location)
      alert('성공')
    }).catch(err => {
      alert('실패')
    })
}

  return (
    <div>
        <div className="img-preview">
          <ImgPreview id="img-preview" src={img} />
          <UploadImage type='file' 
              accept='image/*' 
              id='img' 
              onChange={formSubmit}>
          </UploadImage>
        </div>
    </div>
  );
}

2.2) Node.js 코드

  • 이미지 파일을 해석할 수 있는 multer, s3 연결을 위한 라이브러리들을 설치해준다.
  • 이미지 파일 업로드 후 이미지 파일의 경로를 response로 보내준다.
  • accessKeyID, secretAccessKey 의 경우 AWS 오른쪽 상단 자기 아이디를 클릭 -> 보안자격증명 -> 엑세스 키 에서 발급받을 수 있다.
  • 한국의 경우 region: ap-northeast-2 로 설정하면 된다
// 이미지 업로드
const multer = require('multer');
const AWS = require('aws-sdk');
const multerS3 = require('multer-s3');

const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ACCESSKEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESSKEY,
    region: process.env.AWS_REGION,
})

const upload = multer({
    storage : multerS3({
        s3:s3,
        bucket:'imgstorages',
        key : function(req, file, cb) {
            var ext = file.mimetype.split('/')[1];
            if(!['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(ext)) {
                return cb(new Error('Only images are allowed'));
            }
            cb(null, Date.now() + '.' + file.originalname.split('.').pop());
        }
    }),
    acl : 'public-read-write',
    limits: { fileSize: 5 * 1024 * 1024 },
});

// 이미지 업로드 요청
router.post('/img', upload.single('file'), async (req, res) => {
    console.log(req.file.location)
    res.status(200).json({ location: req.file.location })
});

3. 동작 확인

  • 정상적으로 업로드 됨을 확인할 수 있다.

post-custom-banner

0개의 댓글