JunsuLime / spring-cloud-native-explorer

Spring cloud explorer
1 stars 0 forks source link

AWS S3 와 Spring AWS integeration (Resource) #51

Closed JunsuLime closed 2 years ago

JunsuLime commented 2 years ago

도입

AWS, Spring 을 이용해 정적리소스를 제공하면서 배운 내용 공유드리려합니다.

어쩌다 이 주제로 발표를 하게 되었는지 부터 공유

문앞보관 사진을 관리하는 작업을 하면서, 문앞보관 사진에 대해서 우리가 관리해야하는 니즈가 있어서

그래서.. (다이어그램을 읽으며, 이런 식으로 처리를 했어요!)

이렇게 작업을 진행하였. 작업 진행하면서

  1. AWS 에서 안전하게 정적리소스를 다루는 방법
  2. Spring 을 이용해 리소스를 다루는 방법

에 대해 배운점을 공유하고자 합니다.

본편

은 아래 이어서...

JunsuLime commented 2 years ago

AWS 에서 안전하게 정적리소스를 서빙하자.

보안가이드에서는 안전한 S3 사용자가이드를 제시하고있으며, 우리가 하려는 정적리소스 서빙에 대해서도 해당문서에서 다루고있습니다. 가이드에서는 AWS 의 S3, CloudFront, Route53 서비스를 사용하는것을 사용하는 것을 안내하고 있습니다.

가이드에서 알려주는 서비스들이 무엇인지, 왜 이를 사용해야하는지 간략히 알아보도록 하겠습니다.

S3

S3 는 Simple Storage Service 의 약자로, AWS 에서 제공하는 객체 스토리지 서비스입니다. 우리는 해당 서비스를 이용해 파일 형태의 정보를 저장합니다.

S3 는 "버킷"에 파일을 저장할 수 있으며, "버킷" 단위로 접근제어를 컨트롤 할 수 있습니다. 접근제어는 user 혹은 resource 단위로 설정할 수 있으며, 아무 설정을 하지않을 경우, bucket 은 public access 접근이 막혀있습니다.

OT 에서는 S3를 사용해 사진정보를 저장하였습니다.

저장까지는 어찌했지만, S3의 기본설정은 public access 접근불가입니다. 이를 S3의 설정만을 이용해 접근 가능케 하는 방법 중 하나는, 접근 권한을 public 으로 풀어내는것입니다. 이렇게 접근권한을 풀 경우 S3 에서 제공하는 Object URL 을 통해서 S3 객체에 접근하 수 있습니다.

하지만 Object URL 을 외부로 노출 할 경우 S3 서비스를 사용해 서비스를 하고있는 사실을 노출할 뿐만아니라, 어느 region 에서 서빙하는지, 버킷이름이 무엇인지까지 사용자가 알 수 있게 됩니다.

public resource 로 설정했을 경우 위험성을 막기위해서, 그리고 리소스를 좀더 효과적으로 제공하기위해서 가이드에서는 CloudFront 의 사용을 안내하고 있습니다.

CloudFront

Amazon CloudFront는 .html, .css, .js 및 이미지 파일과 같은 콘텐츠를 사용자에게 더 빨리 배포하도록 지원하는 CDN 서비스입니다.

CDN 이란 "Content Delivery Network"의 약자로, 최종 사용자와 가까운 위치의 엣지 서버에 캐시된 콘텐츠를 저장하여 사용자 대기시간을 최소화하는 역할을 합니다. 뿐만 아니라, CloudFront 에서는 CloudFront 의 도메인을 발급해주어서 위에서 발생한 S3 버킷 노출 이슈를 해결 할 수 있습니다.

그래서 CloudFront 를 사용하면

이렇게 CloudFront 를 제공하면 아래와 같은 url 로 사진을 접근할 수 있습니다. 하지만 이렇게 제공하면 도메인 주소에 대한 가독성이 떨어지기 때문에 가이드에서는 route53 까지 적용을 안내하고 있으며

Route53

Route53 을 적용하면 알아보기 쉬운 도메인으로 사진정보를 제공할 수 있습니다.

여기까지 보안가이드 기반으로 정적리소스를 서빙하는 방법을 알아봤습니다.

JunsuLime commented 2 years ago

이렇게 AWS 를 이용해 어떻게 정적리소스를 안전하게 서빙하는지를 알아보았. AWS 에서 어떻게 다뤄야하는지는 알았고,

그림에서 볼 수 있듯

  1. http 를 통한 사진 리소스 취득
  2. S3 에 사진 저장

두 작업을 Spring 을 다뤄보았습니다.

Spring 을 이용해 리소스를 다루자.

이 이야기를 하려면 Spring 에서 제공하는 두가지 인터페이스에 대해서 알고 가야합니다. 지금 말할 인터페이스가 바로 Resource, ResourceLoader 라는 인터페이스입니다.

Spring Framework > Resource

low level resource 를 다루기위해서 spring 에서는 Resource 인터페이스를 제공합니다.

Resource 는 InputStreamSource 를 상속받은 interface 이며 InputStreamSource 를 통해 java.io 에서 제공하는 InputStream 정보를 가져올 수 있고, byte 정보까지 가져올 수 있어요.

즉, Resource 는 byte 정보를 취득하기위해 spring 에서 추상화한 인터페이스라고 볼수 있는거죠.

이러한 Resource 정보를 취득하기위해서 Spring 에서는 ResourceLoader 라는 인터페이스를 제공하고있어요. interface 에서 확인할 수 있듯, location 정보를 넣으면 관련된 Resource 를 취득할 수 있습니다. 이러한 ResourceLoader 가 어떻게 동작하는지 코드를 통해 살짝 맛만 보시죠.

ResourceLoader 가 기본적으로 http 리소스를 지원하기때문에, 다이어그램에서 Spring Framework 에서 제공하는 기본기능을 통해 http resource 취득까지는 성공했습니다. 그렇다면 S3에 이를 write 하는 작업은 어떻게 할 수 있을까요??

S3에 사진을 저장

AWS 의 S3 SDK를 직접사용하는 것도 방법이겠지만, 우리가 Spring 환경에서 개발을 한다면 Spring 에서 주는 Resource 등의 인터페이스를 최대한 활용해, 휘발성 코드를 제거하는데 노력을 들이는게 좋으 방법이라고 생각합니다.

다행히도 spring 에서는 이미 AWS 와의 통합으로 위한 프로젝트가 이미 있습니다. "Spring Cloud > Spring Cloud for Amazon Web Services" 가 그 친구인데요.

해당 프로젝트에서도 S3 를 다룰 때, Resource, ResourceLoader interface 를 통해 S3 리소스를 다루고 있습니다. 아까 맛봤던 코드 기억나실까요?? DefaultResourceLoader 에서는 ProtocolResolver 를 기반으로 resource 정보를 가져오고 있습니다.

spring-cloud-starter-aws 라는 디펜던시를 추가하면 ProtocolResolver 의 구현체 중 S3ProtocolResolver 가 있는것을 확인할 수 있어요. 그리고 코드를 따라가다보면 Configurer 를 통해 이 친구가 등록이 되는것도 알 수있고요.

그래서 코드에서 볼수있듯, 저 두 빈을 등록해주면 우리는 resourceloader 를 사용하여 S3 리소스를 다룰 수 있게됩니다.

===

여기까지, Spring 을 이용해 Resource 를 다루는 법을 알아보았고요! 전체 summary 한번 하고 마무리하겠습니다.

JunsuLime commented 2 years ago

마무리

JunsuLime commented 2 years ago

참고자료

https://aws.amazon.com/ko/architecture/icons/