[IT]/AWS

[AWS][S3] Presigned URL이란

ee2ee2 2022. 12. 12. 09:52
728x90
반응형

Presigned URL 이란

Presigned URL (미리 서명된 URL) 이란 AWS 자원에 대한 접근 권한을 제공하기 위해서 사용되는 이름 그대로 사전에(미리) 적절한 권한을 가진 자격증명에 의하여 signed된 URL을 말함.

 

필요한 이유는?

S3(Simple Storage Service)의 객체의 경우, Default로 비공개이고 소유자만 접근 가능 함. Bucket Policy나 ACL(Access Control List, 접근 제어 목록)과 같은 제한 설정과 관계없이 소유자의 보안 자격 증명을 사용하여 특정 "유효시간"내에 S3에 PUT, GET을 가능하게 하는 URL을 생성하는 것임. 이 URL을 presigned URL이라 부르며 해당 URL을 통해 임시적으로 객체에 접근 가능하도록 함.

 

주의할 점?

presigned URL은 URL을 아는 모든 사람(권한이 없는 환경/사용자 포함)에게 S3 버킷에 대한 Access 권한을 부여하므로, 꼭 유효시간 설정이 필요함!

 

* S3 Pre-signed URL 생성하기

1) AWS CLI를 통한 url 생성

aws s3 presign s3://'your_bucket_name/your_object' --expires-in 'number(sec)' --region '대상리전'

 

2) Server(Java)를 통한 URL 생성

#미리 aws configure 정보 등록
#단, 설정한 계정은 S3접근 권한을 가진 계정으로 설정되어야 함.

#AWS 설정 (보안의 이유로 생략한 부분이 있음)
cloud:
    aws:
        region: region지역 설정
        credentials:
            profile-name: default
            s3-access-key: $S3_ACCESS_KEY
            s3-secret-access-key: $S3_SECRET_ACCESS_KEY
            access-key: $ACCESS_KEY
            secret-access-key: $SECRET_ACCESS_KEY
        s3:
            bucket: bucket명
            base-dir: baseDir명
            upload-bucket: uploadBucket명
            
            
==========================================================

# presignedURL 생성 부분

import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;

// Set the presigned URL to expire after 15 minute.
java.util.Date expiration = new java.util.Date();
long expTimeMillis = Instant.now().toEpochMilli();

//만료시간 1시간
expTimeMillis += 1000 * 60 * 60 * 1;
expiration.setTime(expTimeMillis);

// Generate the presigned URL.
GeneratePresignedUrlRequest generatePresignedUrlRequest =
            new GeneratePresignedUrlRequest(bucketName, objectKey)
                    .withMethod(HttpMethod.GET)
                    .withExpiration(expiration);

URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);

위와 같이 return 한 url은 front에서 받아 이미지를 업/다운로드를 수행함. 속도면에서 빠름.

front (React.js)에서 사용 방법 예

# 파일 업로드 시, return 받은 URL을 사용하여 업로드 (react.js)
const responseData = await fetch(
    new Request(response.presignedUrl, {
        method: 'POST',
        body: file,
        headers: new Headers({ "Content-Type": "Application/octet-stream" })
    })
);

# 파일 다운로드 시, return 받은 URL을 사용하여 다운로드 (react.js)
const data = {
    name: ‘presign GET’,
    result: '',
    request: {
        type: 'presign',
        data: {
            file_path: filePath,
            docType,
            source,
          },
        },
     };

const response = await connectionStore
    .request({ data })
    .then((result) => {
        // response presign URL을 새 창에서 download
        if (setLoadingState) setLoadingState(false);

        openUrl = result.presignedUrl;
     })
    .catch(() => {
        if (setLoadingState) setLoadingState(false);
    });

** 소스 부분에 생략된 부분이 있을 수 있습니다. 흐름만 봐주세요!

 

참고 자료 

https://heewon26.tistory.com/37

https://bosungtea9416.tistory.com/entry/AWS-S3-pre-signed-url-%EC%9D%B4%EB%9E%80-AWS-CLI-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%82%AC%EC%9A%A9

https://negabaro.github.io/archive/S3-Presigned-URL