티스토리 뷰

 

S3를 퍼블릭으로 관리하게 되면서, 파일을 주기적으로 지워야하는 정책이 추가됐다.

 

S3에서는 다행히 주기적으로 파일을 삭제하는 기능이 있다.

 

바로 수명 주기 규칙이다.

 

S3 > 버킷 > 버킷 선택 > 관리 > 수명 주기 규칙 생성으로 들어간다.

 

 

수명 주기 규칙은 알아보기 쉽게 짓고, 내 목적은 파일 전체를 지우는 거기 때문에, 버킷의 모든 객체 적용을 선택.

 

그리고 이전 버전 영구 삭제를 하루로 설정한다.

 

 

다만, 수명 주기 규칙 생성은 최소 단위가 1일이다.

 

이 간격을 더 짧게 만드는 가장 쉬운 방법은 람다나 서버에서 스케줄러를 돌려서 주기적으로 데이터를 지워주는 방식이다.

 

심플하지만 재미없는 방식이다.

 

조금 색다른 아이디어를 내보자면, S3에 저장된 객체만 퍼블릭하게 접근할 수 있는 시간을 지정할 수 있으면

 

S3 저장소는 프라이빗(안전)하게 사용하면서, 특정 시간 동안만 객체를 퍼블릭하게 노출 시킬 수 있다

 

이 기능도 S3에서 제공해주는데, 이름이 조금 이상하지만 미리 서명된 URL(pre-signed URL)을 활용하는 것이다.

 

먼저 AWS에서 콘솔에서 사용법을 알아보자.


미리 서명된 URL(pre-signed URL)

미리 서명된 URL이란

미리 서명된 URL은 사용자에게 AWS 보안 인증이나 권한이 없어도 비공개 S3 객체에 대한 임시 액세스를 제공합니다. 예를 들어 Alice가 S3 객체에 대한 액세스 권한을 가지고 있고 해당 객체에 대한 액세스 권한을 Bob과 일시적으로 공유하려고 할 경우, Alice는 미리 서명된 GET 요청을 생성하여 Bob과 공유할 수 있으므로 Bob은 Alice의 보안 인증에 액세스하지 않고도 객체를 다운로드할 수 있습니다. HTTP GET 요청과 HTTP PUT 요청에 대해 미리 서명된 URL을 생성할 수 있습니다.

 

이미지를 S3(프라이빗으로 생성된 S3)에 업로드하고 url에 접근한다면 당연히 access denied가 노출된다.

 

S3 > 버킷 > 버킷 선택 > 객체(이미지 파일) 선택 > 객체 작업 > 미리 서명된 URL과 공유

 

 

미리 서명된 URL과 공유 메뉴를 선택하면 아래와 같은 창이 뜬다.

 

 

객체를 외부에 노출하는 시간을 분단위 까지 제어할 수 있다.

 

시간을 지정하고 URL을 생성하면 명시된 것처럼 자동으로 URL이 복사된다.

 

 

1분으로 지정했더니 1분 후부터는 다시 접근이 불가능하다.

 

 

이 과정을 스프링 부트에서도 제어할 수 있다.


코드

아래 URL에서 코드를 그대로 옮겨옴

https://docs.aws.amazon.com/ko_kr/sdk-for-java/latest/developer-guide/examples-s3-presign.html

public String createPresignedUrl(String bucketName, String keyName) {
    try (S3Presigner presigner = S3Presigner.create()) {

        GetObjectRequest objectRequest = GetObjectRequest.builder()
                                                         .bucket(bucketName)
                                                         .key(keyName)
                                                         .build();

        GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
                                                                        .signatureDuration(Duration.ofSeconds(60))
                                                                        .getObjectRequest(objectRequest)
                                                                        .build();

        PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(presignRequest);
        System.out.println("Presigned URL: " + presignedRequest.url().toString());

        return presignedRequest.url().toExternalForm();
    }
}

매서드를 만들고 아래와 같이 불러온다.

PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(presignRequest);

System.out.println("Presigned URL: " + presignedRequest.url().toString());

// Presigned URL: https://presigned-url-test-buckett.s3.ap-northeast-2.amazonaws.com/cat.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20240328T062302Z&X-Amz-SignedHeaders=host&X-Amz-Expires=29&X-Amz-Credential=AKIAUVLNZG2X3MSEHUON%2F20240328%2Fap-northeast-2%2Fs3%2Faws4_request&X-Amz-Signature=4341de2f011660c346566663025c7c86042edcd64287c70bf65a4c756d334dd7

 

잘 동작한다.

 

마치며

개발적으로는 손이 안가는 깔끔한 방법이지만 UX적인 이슈가 제기될 수 있다.

 

URL이 너무 못 생겨서 사용자에게 노출시키기 거북하다는 것이다.

 

이럴 때는 bitly나 자체 개발한 short url을 사용하는게 좋을 것 같다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함