java/spring

[Spring] S3 Pre-Signed URL 생성

danuri 2022. 7. 25. 16:57

기본 세팅

먼저 S3 버킷에 대한 퍼블릭 엑세스 설정이 필요하다. 해당 글을 참고하자.

2022.07.25 - [aws] - [AWS] S3 버킷 퍼블릭 엑세스 설정

 

[AWS] S3 버킷 퍼블릭 엑세스 설정

AWS S3 버킷을 퍼블릭하게 열어두고 사용할 때가 많다. 이번에는 S3 퍼블릭 엑세스에 대한 기본 세팅을 설명한다. 퍼블릭 엑세스 차단 기본적으로 아무 설정 없이 버킷을 생성하면 모든 퍼블릭 엑

gksdudrb922.tistory.com

 

또한, Spring Boot에서 S3 설정 및 접근에 대한 인증 키를 입력해야 한다. 해당 글을 참고하자.

2022.07.25 - [java/spring] - [Spring] AWS S3 접근

 

[Spring] AWS S3 접근

라이브러리 추가 implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' 인증 키 추가 본인 IAM 인증 키를 추가하면 된다. cloud: aws: credentials: instance-profile: false acce..

gksdudrb922.tistory.com

 

Pre-Signed URL

S3 버킷의 객체는 모두 링크를 통해 접근할 수 있다. (조회, 다운로드, 업로드 등)

그러나 S3 객체는 기본적으로 비공개이고, 공개한다 해도 객체와 직접적으로 연결된 S3 링크가 외부에 유출되는 것은 위험하다.

따라서, Pre-Signed URL을 사용하면 편리하다.

객체 소유자는 필요에 따라 자신의 보안 자격 증명을 사용하여 일정 기간 동안 객체 접근을 허가하는 Pre-Signed URL을 만들어 다른 사용자와 객체를 공유할 수 있다.

Pre-Signed  URL은 설정한 기간 이후에 사라지기 때문에 외부 유출에도 큰 위험이 없다.

여기서는 객체를 업로드할 수 있는 Pre-Signed URL을 생성하는 코드를 작성하겠다.

public String getPreSignedUrl(String bucket, String prefix, String fileName) {
    if (!prefix.equals("")) {
        fileName = prefix + "/" + fileName;
    }
    GeneratePresignedUrlRequest generatePresignedUrlRequest = getGeneratePreSignedUrlRequest(bucket, fileName);
    URL url = amazonS3.generatePresignedUrl(generatePresignedUrlRequest);
    return url.toString();
}

private GeneratePresignedUrlRequest getGeneratePreSignedUrlRequest(String bucket, String fileName) {
    GeneratePresignedUrlRequest generatePresignedUrlRequest =
            new GeneratePresignedUrlRequest(bucket, fileName)
                    .withMethod(HttpMethod.PUT)
                    .withExpiration(getPreSignedUrlExpiration());
    generatePresignedUrlRequest.addRequestParameter(
            Headers.S3_CANNED_ACL,
            CannedAccessControlList.PublicRead.toString());
    return generatePresignedUrlRequest;
}

private Date getPreSignedUrlExpiration() {
    Date expiration = new Date();
    long expTimeMillis = expiration.getTime();
    expTimeMillis += 1000 * 60 * 2;
    expiration.setTime(expTimeMillis);
    log.info(expiration.toString());
    return expiration;
}

파라미터는 다음과 같다.
- bucket: 버킷 이름
- prefix: 버킷 내 디렉토리 이름, 없으면 빈 문자열("")
- fileName: 업로드 하고자 하는 파일명

getGeneratePreSignedUrlRequest() 에서 
.withMethod(HttpMethod.PUT)은 업로드용 Pre-Signed URL을 생성하기 때문에, PUT을 지정했다.
.withExpiration()은 URL의 유효 기간을 설정하는 것으로 getPreSignedUrlExpiration()에서 설정한다.

해당 코드로 생성된 Pre-Signed URL을 API 등을 통해 전달하면 사용자는 URL을 통해 원하는 객체를 업로드할 수 있다.

 


 

업로드 뿐만 아니라 조회, 다운로드도 Pre-Signed URL을 이용하면 편리할 것으로 보인다.