CORS에 대해 알아보자

👾·2022년 1월 4일
0

HTTP

목록 보기
2/4
post-custom-banner

CORS에 대해 조사해서 나름대로 정리해본 글입니다.
틀린 부분이 있으면 언제든 댓글로 말씀해주세요🙃

CORS란?🧐

Cross-Origin Resource Sharing

단순히 말하면, "다른 출처" 에서 받아오는 리소스를 제한하는 정책입니다.

여기서 출처(origin)란 url의 프로토콜+호스트+포트번호를 의미합니다.
3가지가 모두 동일한 출처를 same-origin이라고 하며, 3가지 중 하나라도 다르면 cross-origin이 됩니다.

중요한 점은, 출처를 비교하는 것은 서버가 아니라 브라우저입니다.
즉 CORS 정책을 위반하는 리소스 요청을 하더라도, 해당 서버가 same-origin만 허용하는 상태가 아니라면 서버는 정상적으로 응답을 하게 됩니다.
이 이후에 브라우저가 서버의 응답을 분석해서, CORS 정책 위반이라고 판단되면 그 응답을 사용하지 않고 버리는 순서인 것입니다!

SOP (Same-Origin Policy)라는 정책이 웹에 존재합니다.
이는 동일한 출처에서만 리소스를 공유할 수 있음을 나타내는 보안정책입니다.

옛날에는 웹사이트를 만들 때 대부분 하나의 서버에서 브라우저의 모든 요청을 처리했기 때문에 이러한 정책이 존재하였습니다.
이러한 제약 정책 덕분에 사람들은 안전하게 인터넷을 사용할 수 있었습니다.
이러한 정책이 없다면, 아무나 나의 애플리케이션인 척 속여 서버로 요청을 보내 사용자의 정보를 빼내 갈 수 있을 것입니다.

하지만 점점 웹사이트에서 할 수 있는 일들이 많아지고, 다양한 출처의 리소스를 사용해야 할 일이 많아지게 되었습니다.
즉 cross-origin으로의 요청은 보안상으로 제한되었지만, 이러한 요청이 필수적이게 된 것입니다.

그래서 SOP에 몇 가지 예외 조항을 두고, 이 조항에 해당하는 리소스 요청은 출처가 다르더라도 허용하기로 한 것인데, 그중 하나가 CORS 정책을 지킨 리소스 요청입니다. 즉 우리는 CORS로 인해 다른 출처의 리소스에 접근하여 사용할 수 있는 것입니다.

CORS 동작 방법🤨

CORS로 인해 발생하는 문제를 해결하기 위해서는, 먼저 CORS의 동작 방법부터 이해해야 합니다.

기본적으로 웹 클라이언트 애플리케이션이 다른 출처의 리소스를 요청할 때에는 HTTP 프로토콜을 사용하여 요청을 보내게 되는데, 이때 브라우저는 요청 헤더의 Origin 이라는 필드에 요청을 보내는 출처를 함께 담아 보내게 됩니다.
ex) Origin : https://github.com

이후 서버가 이 요청에 대한 응답을 할 때 응답 헤더의 Access-Control-Allow-Origin이라는 값에 "이 리소스를 접근하는 것이 허용된 출처"를 내려주고, 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin를 비교해본 후 이 응답이 유효한지 결정합니다.

기본적인 흐름은 이렇고, 구체적인 동작 방식은 다시 2가지로 나뉘게 됩니다.

1. simple request

단순 요청 방법으로, 서버에게 바로 요청을 보내는 방법입니다.

서버에 API를 요청하고, 서버는 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보냅니다.
브라우저는 이 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.
하지만 서버로 전달하는 요청이 꽤나 까다로운 조건을 만족해야 단순 요청으로 동작하게 됩니다.
일반적인 웹 애플리케이션 개발 시에는 거의 충족하기 어려운 조건들이라 경험하기에는 어려움이 있습니다.

2. preflight request

서버에 예비요청(preflight)을 보내서 안전한지 판단한 후 본 요청을 보내는 방법으로, 가장 일반적인 방법입니다.

preflight 요청은 실제 리소스를 요청하기 전에, OPTIONS이라는 메서드를 통해 실제 요청을 전송할지 판단합니다.
OPTIONS 메서드로 서버에 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보냅니다.

브라우저는 단순 요청과 동일하게 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.
안전하다고 판단되면 다시 본 요청을 보내게 됩니다. 이후 서버가 이 본 요청에 대한 응답을 하면 브라우저는 최종적으로 이 응답 데이터를 자바스크립트에게 넘겨주게 됩니다.

CORS 해결방법

이제는 CORS의 해결 방법 2가지에 대해서도 이해할 수 있습니다.

1) Access-Control-Allow-Origin

서버에서 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보내는 방식으로 CORS 에러를 해결할 수 있습니다.

즉 프론트엔드 개발자가 CORS 에러를 확인하면 서버에 Access-Control-Allow-Origin 등 CORS를 해결할 수 있는 몇 가지 응답 헤더를 포함해달라고 요청하면 됩니다.
Access-Control-Allow-Origin 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용하게 되며, Access-Control-Allow-Origin:https://github.com과 같이 출처를 명시해주면 됩니다.

요약하자면, Cross Origin에서 자원을 요청하기 위해서는 다음과 같은 과정을 거치면 됩니다.

  1. Http 통신 헤더인 Origin 헤더에 요청을 보내는 곳의 정보를 담고, 서버로 요청을 보낸다.
  2. 이후 서버는 Access-Control-Allow-Origin 헤더에 허용된 Origin이라는 정보를 담아 보낸다.
  3. 클라이언트는 헤더의 값과 비교해 정상 응답임을 확인하고 지정된 요청을 보낸다.
  4. 서버는 요청을 수행하고 200OK코드를 응답한다.

이 방법은 서버에서 설정하는 방법으로, 프론트엔드단에서는 불가능합니다.

2) Proxy 사용

CORS를 겪는것은 프론트엔드 부분이므로, 프론트엔드단에서 이를 해결하기 위해서는 proxy를 사용합니다.
프록시를 이용하여 CORS 정책을 지킨 것처럼 브라우저를 속이면서, 원하는 서버와 통신을 할 수 있게 되는 것이죠.

자세히 설명하면, 프론트엔드와 백엔드 사이에 프록시 서버를 두는 방법으로 CORS를 우회하는 것입니다.
즉 브라우저는 localhost에서 요청을 보낸 것으로 알고 있지만, 뒤에서 https://github.com로 요청을 프록싱해주어서 마치 CORS 정책을 지킨 것처럼 브라우저를 속이면서도 원하는 서버와 자유롭게 통신을 할 수 있게 됩니다.

프론트엔드단에서 해결 가능한 방법이지만, 로컬개발환경과는 달리 실제 애플리케이션을 빌드 후 서버에 올리게되면 프록싱이 먹히지 않습니다.
즉 근본적인 해결 방법은 아니므로 1번 방법을 기억하는 게 좋을 것 같습니다.


스스로 CORS에 대해 조사한 내용을 정리해본 내용이므로 부족하거나 틀린 내용이 있을 수 있습니다.🙃

post-custom-banner

0개의 댓글