3 분 소요


CORS(Cross-Origin Resource Sharing)을 번역한 글입니다.

그림 1. CORS principle.



UI 서버를 구축하고 있다고 상상해보십시오.
일부 데이터를 가져오거나 보내려면 원격 API에 연결해야 합니다.
curl로 REST 호출을 테스트할 때는 모든 것이 잘 작동하지만, UI 서버에서는 그렇지 않습니다.

먼저 코드를 확인하고 오타나 실수를 찾지만 아무 문제가 없습니다.
URL을 google.com 처럼 다른 것으로 변경하고 http 호출이 작동하는지 확인합니다.
이 문제는 특정 API를 호출 할 때만 나타납니다.
그러나 커맨드 라인이나 Postman을 사용하면 완벽하게 작동합니다.

도대체 뭐가 문제일까요?


그림 2. CORS 에러.


바로, CORS 때문입니다.

Angular/React/whatever 에서 CORS를 수정하는 방법을 묻기 위해 스택 오버플로를 검색하기 전에
CORS 가 실제로 무엇인지, 왜 UI에서 수정할 수 없는 지 알아 보겠습니다.




CORS 란?

CORSCross-Origin Resource Sharing 의 약자입니다.
이해하기는 정말 간단하지만 CORS에 대한 많은 오해와 해결되지 않는 솔루션 이 많이 있습니다.

CORS 에 의해 차단되면 많은 사람들이 Google에서 CORS 솔루션을 검색하고 헤더에 추가 내용을
처리하는 몇 줄의 코드를 복사하여 붙여넣고 진행합니다.
이로 인해 일시적으로 문제가 해결될 수도 있지만, 엄청난 보안 위험을 초래할 수도 있습니다.

이 부분은 나중에 이야기하고, 먼저 CORS 가 무엇인지 알아보겠습니다.

CORS 는 모든 최신 웹 브라우저에 내장된 보안 메커니즘입니다.
(맞습니다! 웹 브라우저에 포함되어 있습니다! 이것이 curl 호출이 잘 작동하는 이유입니다)
기본적으로 Frontend 에서 원본(Origin)(대부분의 경우에 해당하는 도메인, 프로토콜 및 포트)이
다른 API 로의 모든 http 요청을 차단합니다.


이 메커니즘은 어떻게 작동할까요?
데이터를 API에 업로드하는 UI에 ‘업로드’버튼이 있다고 가정해 보겠습니다.
HTML 코드에서 이 버튼을 http POST 호출을 수행하도록 JavaScript 함수에 바인딩합니다.


그림 3. Javascript POST.


따라서 해당 버튼을 클릭하면 HTTP POST가 API로 전송될 것 같지만, 브라우저는 내부에서
API에 HTTP OPTIONS 요청을 보냅니다.
일반적으로 API는 브라우저가 수행할 수 있는 작업을 알려주는 데이터로 응답합니다.

이제 여기서 언급할 한 가지: HTTP OPTIONS 는 요청이 non-simple 요청으로 간주되는 경우
실제 요청보다 먼저 전송됩니다.
non-simple 요청은 application/x-www-form-urlencoded, multipart/form-data 또는
text-plain(예: JSON) 이외의 콘텐츠 유형이 있거나 요청에 쿠키가 포함된 경우입니다.
(그래서 거의 대부분의 요청입니다.)

이제 CORS에 대해 이야기하겠습니다.
아래는 OPTIONS 에 대한 응답과 함께 서버에서 다시 보낸 헤더의 예제 입니다.
(서버에서 보냈기 때문에 CORS는 UI 코드에서 수정할 수 없습니다.)
Access-Control-* 헤더를 살펴보고 Access-Control-Allow-Origin 을 살펴보겠습니다:



그림 4. 서버의 응답 헤더.



상황은 다음과 같습니다.
요청된 API 호출을 보내기 전에 브라우저가 API를 요청하여 ‘보안 검사’를 수행합니다.
(OPTIONS 호출을 통해 누가 무엇을 할 수 있는지를 확인합니다.)

CORS 문제는 API가 ‘예, 브라우저 여러분, 이 호출을 할 수 있습니까?’ 라는 요청에 응답하지
않을 때 발생합니다.
따라서 위의 그림에서 볼 수 있듯이 내 API는 내 UI 인 localhost가 OPTIONS, HEAD, DELETE,
POST, GET 호출을 처리할 수 있다고 응답했습니다.

이것이 CORS에 대한 모든 문제의 핵심입니다.
CORS를 수정하려면 API가 적절한 헤더(Access-Control-Allow-*)를 전송하고 있는지
확인해야 합니다.
그렇기 때문에 UI에서 수정할 수있는 문제가 아니며, curl이 아닌 브라우저에서만 문제가
발생하는 것입니다.

브라우저가 호출을 확인하고 결국 차단하기 때문입니다.




해결방법과 보안

그렇다면 보안 허점을 만들지 않고 올바르게 해결할 수 있을까요?
앞서 언급했듯이 이러한 오류가 발생하는 사람들은 종종 해결책을 찾기 위해 Google을
검색하고 적절한 헤더를 추가하는 코드 몇 줄를 복사하여 붙여 넣습니다.
문제는 대부분의 경우 이러한 솔루션Access-Control-Allow-Origin : *
사용한다는 것입니다.
즉, 기본적으로 누구나 API에 액세스 할 수 있도록 허용합니다.

내 API에 대한 인증이 있기 때문에 문제가 없다고 말할 수 있습니다.
만약 그렇다면 이 솔루션은 효과가 없습니다. 브라우저의 호출에 Authorization 헤더가
포함되어 있는 경우 Access-Control-Allow-Origin의 값은 *일 수 없습니다.


따라서 알아야 할 핵심 사항은 다음과 같습니다.

  • CORS는 웹 브라우저에 내장된 메커니즘으로 UI 코드 문제가 아닙니다.
  • CORS 문제를 해결하려면 API 측에서 수정해야 합니다.


하지만 그 API에 접근할 수 없다면, 두 가지 옵션이 있습니다.

  • API 관리자에게 CORS 지원 수정/추가 요청
  • 미들웨어 생성


첫 번째 옵션은 분명합니다.
액세스하려는 API가 회사 API인 경우 백엔드 개발자에게 가서 CORS 지원을 추가하도록
요청하면 됩니다.
이를 수행하는 방법은 사용하는 프레임워크에 따라 다릅니다.
때로는 패키지를 설치하는 것만큼 쉬울 때도 있고 API 코드에 수동으로 헤더를 추가해야
하는 경우도 있습니다.

API를 타사가 제공한 경우 개발사의 지원이나 Github 또는 다른 방법을 통해 해결할 수 있습니다.
즉, 두 번째 옵션을 사용할 수 있습니다.

두 번째 옵션은 미들웨어를 구축하는 것입니다. CORS 는 브라우저에서만 차단되었기 때문에,
기본적으로 원하는 API에서 응답을 받고 CORS 관련 헤더를 맨 위에 추가하고, UI로 다시 보내는
프록시와 유사한 구성 요소를 구축하는 것은 API 서버에 HTTP 헤더를 추가하는 것만큼 간단합니다.

이렇게 하여 해당 API에 직접 연결하지 않고 미들웨어에 연결할 수 있습니다.
이 방법은 최선의 해결책은 아니지만 정말로 필요한 경우에 문제를 해결할 수 있습니다.

또 다른 사용 사례가 있습니다. 관리하는 서버에 코드를 직접 변경할 수는 없지만 CORS 지원을
추가해야 할 경우, Nginx를 설치하여 Nginx 구성에 헤더를 추가하고 해당 서버를 백엔드로 배치할 수
있습니다.

이 포스트를 통해서 CORS 문제에 대한 해결책뿐만 아니라 작동하는 방식에 대해서도 배웠습니다.




참고자료

댓글남기기