CORS (Cross Origin Resource Sharing, 교차 오리진 리소스 공유)
Origin은 체계로 즉 프로토콜이자 호스트, 도메인, 그리고 포트 예) https://www.example.com (implied port is 443 for HTTPS, 80 for HTTP) 체계가 HTTP, 호스트가 www.example.com,포트가 443(HTTP)인 오리진
즉, CORS는 리소스를 다른 오리진에서 얻을 수 있는 것으로 웹브라우저는 기본적인 보안으로 CORS를 갖추며 웹사이트를 방문했을 때 다른 오리진이 허락할 때만 요청을 보낼 수 있도록 허락하는 설정인 브라우저 기본 보안임
같은 오리진 : http://example.com/app1 & http://example.com/app2 다른(교차) 오리진 : : http://www.example.com & http://other.example.com 같은 오리진은 웹 브라우저 간 요청이 가능하지만, 다른 오리진의 경우 올바른 CORS 헤더 (Access-Control-Allow-Origin) 가 없으면 웹 브라우저가 해당 요청을 차단
CORS – Diagram
웹 브라우저에서 첫 번째 웹 서버는 URL이 같아 Origin이며, 두 번째 웹서버는 URL이 달라 Cross Origin 웹 브라우저는 교차 오리진에서 사전 요청(Preflight Request)을 전송하여 요청을 발생시키는 것이 가능한지 물어봄 교차 오리진은 Access-Origin-Allow-Origin을 통해 해당 웹사이트가 허용되는지를 판단한 후 일치할 경우 허용하며 GET, PUT, DELETE 메소드 (CORS 메소드)를 승인하므로 파일을 가져오거나 삭제하거나 업데이트할 수 있게 됨 이전에 전송받은 CORS 헤더가 웹 브라우저의 해당 요청을 허용했으므로 교차 오리진 URL에 대한 GET이 가능해짐
S3 CORS
클라이언트가 웹사이트로 활성화된 S3 버킷에 대해 교차 오리진을 요청하는 경우 올바른 CORS 헤더를 활성화해야 함
전체 오리진 이름을 지정해서 특정 오리진에 대해 허용할 수도 있고 *로 모든 오리진을 허용할 수도 있음
웹 브라우저는 웹사이트로 활성화된 상태인 첫 번째 버킷에서 HTML 파일을 가져올 수 있음 두 번째 버킷을 교차 오리진 버킷으로 웹사이트로 활성화된 상태이며 동일한 파일을 가지고 있음 첫 번째 버킷에 GET index.html을 전송하면 웹 사이트가 웹 브라우저로 index.html 파일을 전송해 줌 다른 파일을 위해 두 번째 버킷에 GET을 요청할 경우 버킷에 올바른 CORS 헤더로 구성되어 있을 경우에만 요청을 보낼 수 있음 즉, 교차 오리진 버킷에는 CORS 헤더가 구성되어야 함
<S3 CORS 실습>
AWS 내 CORS 설정법 index.html 파일로 가면 주석으로 달려 있는 CORS 데모 부분의 주석 처리를 해제 이는 스크립트를 실행하고 이 스크립트는 extra-page.html을 호출해서 extra-page.html에 대해 response 텍스트를 반환 즉, index.html에서 또 다른 HTML 문서를 로드하고 이때 또 다른 HTML 문서는 extra-page.html로 추가 페이지를 성공적으로 로드했다는 텍스트가 반환됨 그러므로 이러한 index.html의 새로운 버전과 extra-page.html을 S3 버킷에 업로드한 후 다시 웹사이트를 열게 됨 그러면 아래에 추가 페이지를 성공적으로 로드했다는 메시지가 표시되며 주소에 /extra-page.html을 입력하면 이 문장만 뜸 이는 동일한 버킷에 index.html 파일과 extra-page.html 파일이 있으므로 즉, 동일한 오리진에 있어 가능한 것
index.html의 CORS 데모 부분
다른 오리진일 때, CORS 쿼리 테스트 먼저 새로운 버킷의 이름을 demo-stephane-cors-2020로 하고 리전은 EU, 공개 액세스 차단은 해제, 웹사이트로 설정해 생성 아직은 웹 사이트에 들어가지지 않으므로 Permissions로 이동해 공개 상태에 대한 버킷 정책을 위의 것을 복사해 똑같이 설정 이제 버킷이 공개 상태가 되었으므로 extra-page.html을 찾아서 파일을 업로드하고 URL을 입력하면 성공적으로 로드
이후 첫 번째 메인 버킷으로 돌아가서 extra-page.html을 삭제하고 /extra-page.html을 보면 오류가 발생해 로드할 수 없음 그러므로 index.html 파일을 수정해서 새 버킷 URL에서 이 문서를 가지고 오도록 하여 다시 해당 파일을 메인 버킷에 업로드 그러므로 다시 새로고침을 하면 새 버킷에서 extra-page.html 파일을 가지고 오는 작업이 당연히 가능해질 것으로 예상
CORS 데모를 진행하기 위해 크롬 개발자 도구를 사용하면 요청을 전송하는 동안 어떤 변화가 생기는지 직접 볼 수 있음 이 상태로 다시 새로고침을 하면 오류 텍스트는 더이상 표시되지 않으나 오류 메시지로 해당 오리진에서 페이지를 불러올 때 즉, 두 번째 버킷으로 첫 번째 버킷에서 올 때 Access-Control-Allow-Origin 헤더가 없었으므로 CORS 정책에 따라 요청된 리소스가 차단되었다고 나오게 됨 그러므로 이제 두 번째 정책에 CORS 정책을 설정해줘야 이러한 오류가 발생하지 않고 첫 번째 버킷에 요청을 전송할 수 있음
이를 위해 두 번째 버킷으로 이동해서 Permissions의 Cross-Origin resource sharing CORS 설정을 JSON으로 정의해야 함 이를 위해 CORS_CONFIG.json 파일을 복사한 후, 허용된 오리진인 HTTP로 시작하는 첫 번째 버킷의 URL에서 마지막 /를 삭제 이를 통해 오리진이 두 번째 버킷에 요청을 전송할 수 있게 되어 새로고침을 해보면 추가 페이지가 성공적으로 로드됨
또한 크롬 개발자 도구의 Networks 탭에서 요청의 헤더를 보면 응답 헤더로 Access-Control-Allow-Origin 헤더가 나타남 그리고 여기에는 첫 번째 버킷의 전체 HTTP URL이 포함되어 있기 때문에 브라우저가 두 번째 버킷에서 두 번째 URL을 로드하는 작업이 가능했던 것임
수정된 index.html 파일CORS 정책을 설정해주지 않아서 추가 페이지가 로드되지 않음CORS_CONFIG.jsonCross-Origin resource sharing CORS 설정을 JSON으로 정의추가 페이지가 성공적으로 로드Network 탭