[Develope]/Cloud&Docker

AWS CORS 설정 (S3/Cloudfornt)

하늘을닮은호수M 2023. 3. 28. 08:53
반응형

CORS 란?

참조 : https://velog.io/@kimsehwan96/S3-CORS-%ED%97%A4%EB%8D%94-%EA%B4%80%EB%A0%A8-%EC%9D%B4%EC%8A%88-%ED%95%B4%EA%B2%B0%EB%B0%A9%EB%B2%95-html2canvas-lottie

우선 CORS 라는 개념을 알고 가야 한다.

CORS란 Cross Origin Resource Sharing 을 의미한다.
우리말로 번역해보면 교차 출처 리소스 공유라고 번역 할 수 있다.

CORS는 웹 브라우저에서 보안상의 이유로 도입되었는데. 현재 사용자가 접속한 웹 애플리케이션이 다른 출처의 리소스를 불러올 때, Access-Control-Allow-Origin 헤더를 보내주지 않으면 브라우저가 그 리소스를 거부하는 보안 정책(?) 이라고 할 수 있다.

풀어서 쉽게 설명하면 다음과 같다.

현재 유저는 https://aaaaaa.com를 브라우저를 통해 접속했다.
 https://aaaaaa.com은 별도의 API 및 리소스 서버를 두어서, 웹 애플리케이션에 필요한 이미지나 텍스트들을 https://bbbbbb.com 에서 불러온다고 해보자.

즉 현재 유저가 보고있는 웹 애플리케이션의 도메인과, 실제 리소스를 불러와서 사용할 서버의 도메인이 다르기때문에 웹 브라우저는 Access-Control-Allow-Origin 헤더가 리소스 서버의 응답에 적절히 들어있지 않다면 사용하기를 거부한다.

개발하다 한번쯤은 겪는 CORS 에러...

이 에러를 해결하기 위한 방법은 매우 간단한데, 응답을 보내주는 서버측에서 Access-Control-Allow-Origin 헤더에 적절한 값을 담아서 보내주면 된다.

이런식으로 서버측에서 access-control-allow-origin 헤더에 적절한 응답을 넣어주면 된다.

보통은 개발의 편의성을 위해 access-control-allow-origin : * 을 넣어주는 편인데, 어떤 Origin에서 요청하든 허용하겠다는 의미이다. (localhost:3000 이든,, IwillHackYou.com 같은 위험해 보이는 도메인이든..)

 

CORS 작동 방식

참조 : https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/cors.html

가장 간단한 경우 브라우저 스크립트는 다른 도메인 내 서버의 리소스에 대해 GET 요청을 수행합니다. 요청이 GET 요청을 제출하도록 승인된 도메인에서 전송된 경우 해당 서버의 CORS 구성에 따라 cross-origin 서버는 요청된 리소스를 반환하여 응답합니다.

요청하는 도메인 또는 HTTP 요청 유형이 승인되지 않은 경우에는 요청이 거부됩니다. 그러나 CORS는 요청을 실제로 제출하기 전에 요청을 사전에 보낼 수 있습니다. 이 경우 preflight 요청은 OPTIONS 액세스 요청 작업을 전송하는 방식으로 이루어집니다. cross-origin 서버의 CORS 구성이 요청하는 도메인에 대한 액세스 권한을 부여하는 경우 서버에서는 요청하는 도메인이 요청한 리소스에 대해 수행 가능한 HTTP 요청 유형을 모두 나열하는 preflight 응답으로 회신합니다.

 

원본 요청 정책 설정하기

참조 : https://bigboss.dev/2021/11/cloudfront-settings-to-use-s3-cors/

CloudFront는 기본적으로 “클라이언트”로부터 받은 요청 헤더, 쿠키, 쿼리 문자열을 “원본”으로 전달하지 않습니다. 이 글에서 “클라이언트”는 웹 브라우저이고 “원본”은 S3입니다. S3의 CORS 정책을 이용하려면 최소한 origin 헤더는 S3로 전달되어야 하고, 필요에 따라 access-control-request-headers와 access-control-request-method도 전달될 수 있습니다.

CloudFront에서 설정하고자 하는 배포를 선택하고 동작 탭에서 편집 페이지로 이동합니다. 동작 편집 페이지 중간쯤에 “캐시 키 및 원본 요청”이 있고 별다른 설정을 하지 않았다면 “Cache policy and origin request policy (recommended)”가 선택되어 있을 것입니다. 그 아래에 “원본 요청 정책 – 선택 사항”이라는 항목이 있는데 아무것도 선택되어 있지 않습니다. 이 항목을 “CORS-S3Origin”으로 선택하고 저장합니다.

curl 또는 Postman을 이용하여, origin 헤더에 “http://localhost”를 포함한 HTTP GET 요청을 보냅니다. 그러면 헤더에 “Access-Control-Allow-Origin: *”이 포함된 HTTP 응답을 받을 수 있습니다. (S3에 CORS 정책이 미리 설정되어 있어야 합니다.)

여기서 끝인 줄 알았습니다. 그런데 HTTP 요청에 origin 헤더를 포함하지 않아도 HTTP 응답에 “Access-Control-Allow-Origin: *”이 포함되고 있었습니다. 아, 뭐가 문제지? 여러 번의 재시도와 구글링 끝에 알게 된 결론은, CloudFront는 기본적으로 요청 헤더에 뭐가 들어있든 상관없이 캐싱을 한다는 것입니다.

캐시 정책 설정하기

아까 설정한 동작 편집 페이지 중간쯤에 있는 “캐시 키 및 원본 요청”을 살펴봅니다. “캐시 정책”에 “CachingOptimized”가 선택되어 있습니다. 직역하면 “최적화된 캐싱”이니 이 녀석이 문제라고는 생각하지 못했습니다.

관리형 정책 중에는 쓸만한 것이 보이지 않습니다. 새로운 정책을 만들기 위해 바로 아래의 “정책 생성”을 클릭하면 새 창이 열립니다. 이름은 대충 “CachingForCORS” 정도로 써줍니다. “캐시 키 설정” 중 “헤더”에 “Origin”을 추가합니다. 다른 건 건드리지 않고 “생성” 버튼을 클릭합니다.

동작 편집 페이지로 돌아와서 “캐시 정책”을 새로고침하면 조금 전에 만든 “CachingForCORS”를 선택할 수 있습니다. 이렇게 캐시 정책을 선택하고 저장합니다.

반응형