리액트 s3로 이미지 업로드

5o_hyun·2023년 12월 21일
0
post-custom-banner

S3 버킷생성

  1. aws s3에 들어가 버킷을 생성한다.

  2. 버킷이름을 설정해주고, 모든엑세스허용으로 변경

  3. 권한에 들어간다.

  4. 버킷정책과 CORS정책 수정해준다.
    1) 버킷정책수정

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

2) CORS정책수정

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "PUT",
            "POST",
            "DELETE",
            "GET"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]
  1. 엑세스키발급

오른쪽 맨위에 내계정을 누르고 보안자격증명을 선택한다.

액세스키발급

이러면 준비는 끝!

.env 설정

보안이 유지되어야하는것은 깃허브에 안올라가게끔 루트에 .env파일을 만들어서 엑세스키를 넣어준다.

NEXT_PUBLIC_S3_ACCESS_KEY_ID="엑세스키발급시 엑세스키ID"
NEXT_PUBLIC_S3_SECRET_ACCESS_KEY="엑세스키발급시 엑세스시크릿키"

이미지업로드

나는 1.미리보기 2.업로드 두가지 기능을 만들었다.
imageFile 에는 미리보기기능
imageSrc 에는 파일객체를 담아 업로드할것이다.

1.미리보기

imageSrc에 파일리더기가 읽어서 미리보기 할수있는기능을 만들었다.
< img src={imageSrc}/> 를 사용하면 미리보기 이미지가 나온다.

// 프로필이미지 미리보기
  const [imageFile, setImageFile] = useState();
  const [imageSrc, setImageSrc]: any = useState(null);

  const handleUpload = (e: any) => {
    const file = e.fileList[0].originFileObj;
    // 1) 파일리더기로 업로드한 파일객체를 readAsDataURL로 파일객체를 읽어옴
    const reader = new FileReader();
    reader.readAsDataURL(file);
    return new Promise<void>((resolve) => {
      // 2) imageSrc에 파일의 콘텐츠를 저장하고,
      reader.onload = () => {
        setImageSrc(reader.result || null);
        resolve();
      };
      // 3) 유저정보에 imageSrc부여 ======> 미리보기끝
      setUserInfo((prev) => ({
        ...prev,
        ['photo']: imageSrc,
      }));
      // 4) 이미지파일 넣어주기
      const fileFormat = file.name.split('.').reverse()[0];
      setUserInfo((prev) => ({
        ...prev,
        ['photo']: 'users/' + user?.id + '.' + fileFormat,
      }));
      setImageFile(file);
      toggleOpenPhotoMethod();
    });
  };

2.업로드

file 객체를 받으면 업로드되게끔 만들었다. 이제 업로드할곳에 s3Upload(파일);만 하면 실행완료

// 프로필이미지 업로드
  AWS.config.update({
    region: 'ap-northeast-2',
    accessKeyId: process.env.NEXT_PUBLIC_S3_ACCESS_KEY_ID,
    secretAccessKey: process.env.NEXT_PUBLIC_S3_SECRET_ACCESS_KEY,
  });

  const s3Upload = async (file: File) => {
    const fileFormat = file.name.split('.').reverse()[0];

    const upload = new AWS.S3.ManagedUpload({
      params: {
        Bucket: 'somelogimg', // 버킷이름
        Key: 'users/' + user?.id + '.' + fileFormat, // 경로와이름설정
        Body: file, // 파일객체
        ContentType: file.type,
      },
    });

    const promise = upload.promise();
    promise.then(
      function () {
        window.setTimeout(function () {
          console.log('업로드');
        }, 2000);
      },
      function (err) {
        console.log('에러', err);
      },
    );
  };

미리보기파일은 파일리더기에만 읽혀서 실제로 저장되지않기때문에 상관없지만,
업로드는 바로 업로드되는게아니라 일단 임시로갖고있다가 저장버튼을 누르면 업로드되게끔 개발했다.

const onSave = () => {
    s3Upload(imageFile); // 저장버튼 누르면 업로드되게.
    updateUserInfo.mutate(userInfo as any);
  };
profile
학생 점심 좀 차려
post-custom-banner

0개의 댓글