background
S31분

S3 업로드

2025년 5월 15일

S3에 이미지 업로드하기

S3란?

  • AWS에서 제공하는 객체 스토리지 서비스로, 이미지, 동영상, 문서 등 다양한 파일을 저장할 수 있는 안정적이고 확장 가능한 저장소입니다.
  • 데이터를 버킷(bucket) 단위로 관리하며, 각 객체(파일)는 고유한 키(key)를 가지고 버킷에 저장됩니다.
  • 백엔드에서 접근하여 파일을 저장할 수도 있지만 프론트엔드에서도 접근하여 파일을 저장할 수 있습니다.
    • 프론트엔드에서 접근하기 위해서는 Presigned URL이 필요합니다.

Presigned URL이란?

  • Presigned URL은 AWS S3 버킷에 제한된 시간 동안 직접 접근 가능한 임시 URL입니다.
  • 백엔드에서 생성하고, 클라이언트는 이 URL을 통해 S3에 직접 파일을 업로드할 수 있습니다.
  • 서버가 파일 데이터를 직접 받지 않으므로 트래픽 감소보안성 향상 효과가 있습니다.

프론트에서 S3에 업로드 하는 방법

  1. 백엔드로부터 presigned URL을 받아옵니다.

    • 백엔드와 협의해서 필요한 데이터를 전송하고 presigned URL을 받아옵니다.

    예시)

    javascript
    import axios from 'axios';
    
    const getImageUploadUrl = async (fileName: string): Promise<string> => {
      try {
        // 백엔드에 fileName(ex: sample.jpg)을 전송하고 presigned URL을 수신 
        const response = await axios.post('/api/presigned-url', { fileName });
        
        if (!response.data || !response.data.presignedUrl) {
          throw new Error("Presigned URL을 가져오는데 실패했습니다.");
        }
    
        return response.data.presignedUrl;
      } catch (err) {
        throw err;
      }
    };
    
    • 받아온 presigned URL은 다음과 같은 형태가 됩니다.
    javascript
    https://tobe-continued-assets.s3.ap-northeast-2.amazonaws.com/store/fbba7f75-3925-4193-a566-a7b51f0a311e_sample.jpg?X-Amz-Algorithm=...(생략)
    
    • 파일 이름까지(위에서는 sample.jpg)가 해당 S3의 실제 파일 저장 경로를 의미합니다.
    • ? 뒤쪽의 파라미터 부분들은 민감한 인증 정보이므로, 되도록 노출을 피해야 합니다. (서명, 인증 등)
    • 버킷이 public-read로 설정되어 있거나, presigned URL 생성 시 ACL이 public-read로 설정되었다면 ? 앞의 URL만으로도 파일 접근이 가능합니다. 단, 일반적으로 presigned URL은 private 버킷에 대한 임시 접근을 위해 사용됩니다.
    • 발급 받은 presigned URL을 통해 PUT 요청으로 이미지를 업로드 할 수 있습니다.

    예시)

    javascript
    import axios from 'axios';
    
    const uploadFileToS3 = async (presignedUrl: string, file: File) => {
      try {
        await axios.put(presignedUrl, file, {
          headers: {
            'Content-Type': file.type, // presigned URL 생성 시 설정한 Content-Type과 일치해야 함
          },
        });
    
        console.log('업로드 성공');
      } catch (error) {
        console.error('업로드 실패', error);
        throw error;
      }
    };
    

    ※ Delete는 보안 상 문제로 보통 백엔드에서 처리합니다.

태그

#S3