-
S3 pre-signed url 만들기(Kotlin + Spring)프로젝트/미디어 스트리밍 서버 프로젝트 2023. 1. 6. 00:01반응형
pre-sigend url이란?
모든 객체 및 버킷은 기본적으로 private입니다.
보통 고객/사용자가 AWS 보안 자격 증명을 얻어 버킷에 접근하여 객체에 업로드합니다.
이때 pre-signed url을 통해 선택적으로 객체를 공유하여 보안 자격 증명이나 권한 없이 버킷에 객체를 업로드하는 것을 허용할 수 있습니다.
보통 pre-sigend url의 기능은 이를 만든 사용자의 권한에 의해 제한됩니다.
pre-sigend url을 만들기 위해서는 보안 자격 증명을 제공하고 버킷 이름, 객체 키, HTTP 메서드 및 만료 날짜와 시간을 지정해야 합니다.
지정된 기간 동안만 유효합니다.
pre-signed url 동작 과정
그림 1 [그림 1] 과정을 글로 설명하면 다음과 같습니다.
1. 클라이언트가 서버에게 presigned URL 요청 2. 서버는 AWS credential 인증과정을 거쳐 S3에 요청 이때 bucket name과 key(파일 경로) , HTTP 메서드, 만료시간을 넣고 pre-signed url 생성 3. AWS S3로부터 presigned URL 반환받음 4. presigned URL 클라이언트에게 반환 5. 클라이언트는 presigned URL으로 HTTP 요청(PUT이라고 가정) 이후 presigend URL에 지정되었던 bucket name, key에 해당 object 업로드 됨 6. 클라이언트는 Server에게 업로드를 했음을 알림
pre-sighed url 장점, 사용하는 이유
대규모 트래픽 처리
비디오 업로드는 매우 부하가 큰 작업입니다.
JSON을 주고받는 일반 API요청에 비하면 훨씬 부하가 큽니다.
따라서 비디오 업로드가 백엔드 서버를 거치게 되면 백엔드 서버가 금방 죽을 수 있으며, 혹은 동시 업로드 요청수를 제한하게 되면 유저 경험이 떨어지게 됩니다.
보안 관점
프론트에서 바로 S3와 같은 파일 저장소나 데이터베이스로 데이터를 보내지 않고 백엔드를 거치는 이유는 보안 문제 때문입니다.
따라서 백엔드에서는 presignedUrl 생성으로 보안 절차 작업만 진행해주고 Cleint가 AWS S3에 바로 업로드할 수 있게 지원합니다.
Spring , Kotlin + AWS pre-signed url 적용법
필요한 사전 지식- AWS Credential 설정법- PostMan 사용법build.gradle.ktsdependencies{ val awssdkVersion = "1.12.220" implementation("com.amazonaws:aws-java-sdk-s3:$awssdkVersion") }
AwsS3config
@Configuration class AwsS3Config { @Bean fun s3Client(): AmazonS3 = AmazonS3ClientBuilder .standard() .withRegion(Regions.AP_NORTHEAST_2) // ap-northeast-2 (Seoul) .build() }
S3Service
@Service class S3Service(private val s3Client: AmazonS3) { @Value("\${aws.s3.bucket.name}") lateinit var bucketName: String /* objectKey는 해당 bucket의 파일이 저장될 경로, 파일의 이름을 나타냅니다. 즉, pre-signed url을 반환할때는 이미 어떤 요청이 오게될지 (GET, PUT 등) 어떤 버킷의 어떤 경로, 이름으로 저장될지가 이미 정해져 있게 됩니다. */ fun generatePreSignedUrl(objectKey: String): String { val expiration = Date() expiration.time += EXPIRE_PERIOD val generatePreSignedUrlRequest: GeneratePresignedUrlRequest = GeneratePresignedUrlRequest(bucketName, objectKey) .withMethod(HttpMethod.PUT) .withExpiration(expiration) val url: URL = s3Client.generatePresignedUrl(generatePreSignedUrlRequest) return url.toString() } companion object { const val EXPIRE_PERIOD = 1000 * 60 * 3 } }
VideoController
@RestController @RequestMapping("video") class VideoController( val s3Service: S3Service, ) { @PostMapping fun preSignedUrl(): String { return s3Service.generatePreSignedUrl("presigned/test.mp4") }
인자로 들어가는 "presigned/test.mp4" 는 objectKey로 S3에 최종 저장되는 경로는 bucket_name/presigned/test.mp4가 됩니다.
PostMan 요청
그림 2 [그림 2]와 같이 POST 요청을 보내면 200OK 응답과 함께 presigned url을 반환받습니다.
그림 3 이제 해당 presigned url을 클릭하고 PUT 메서드를 선택합니다.
이후 Body -> binary -> select file을 선택하여 video file을 선택하고 PUT 요청을 보내면 200 OK 응답이 받아집니다.
그림 4 이후 버킷이름/지정한경로로 이동하게 되면 Object가 저장되어 있습니다.
참고자료
https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/using-presigned-url.html
미리 서명된 URL 사용 - Amazon Simple Storage Service
2019년 3월 20일 이후에 시작된 모든 리전에 대해 요청이 잘못된 Amazon S3 위치에 도달하면 Amazon S3는 HTTP 400 Bad Request 오류를 반환합니다.
docs.aws.amazon.com
'프로젝트 > 미디어 스트리밍 서버 프로젝트' 카테고리의 다른 글
DataGrip으로 테이블 DDL DML 추출하기 (0) 2023.01.31 CDN이란? (0) 2023.01.17 Adaptive Bitrate와 MPD파일 (0) 2023.01.05 스프링과 스트리밍 서버 (0) 2022.12.23 [Kotlin] AWS S3에 업로드하기 (0) 2022.12.19