CORS 이슈 해결하기

이강현·2023년 3월 5일
7
post-thumbnail

cors-policy-error-image

이전에 진행했던 프로젝트에서 URL을 이용해 HTML 소스를 긁어오는 기능을 브라우저 상에서 구현하다가 위 이미지와 같이 CORS 정책 관련 오류를 마주쳤었고, 프록시 서버를 별도로 구축하여 문제를 해결할 수 있었습니다.

해결 과정에서 배운 CORS 개념과 관련 문제를 상황에 맞게 해결하는 방법에 대해 블로그를 통해 공유합니다.


CORS는 무엇인가?

MDN의 CORS에 관한 글에서는 CORS를 아래와 같이 설명합니다.

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.

쉽게 이해하기 어려운 내용이니 차근차근 이해해보겠습니다.

우선 리소스를 자신의 출처(도메인, 프로토콜, 포트)와 다른 출처에 요청을 보내는 것을 Cross-Origin Request라고 합니다. (예를 들어, https://a.com 에서 https://b.com/data.json 을 요청)

그리고 이러한 Cross-Origin Request에 대한 Response를 받으려면, 즉 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여받으려면 Remote Origin(요청에 대한 응답을 보내는 쪽)에서 추가 HTTP 헤더를 포함하여 Response를 전송하여 브라우저에 알려주어야 합니다.

이러한 체제를 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)라고 합니다.

만약 해당 HTTP 헤더를 포함한 Response를 받지 못한 경우, 브라우저는 보안 상의 이유로 Cross-Origin Request를 차단하는데, 이러한 브라우저 상의 정책을 CORS(Cross-Origin Resource Sharing) 정책이라고 합니다.

다른 출처?

위에서 "다른 출처"를 언급하였습니다. 그렇다면 "다르다"의 기준이 무엇일까요?

이는 Cross-Origin이라는 단어에도 나와있지만, 오리진(origin)이 다른 경우를 말합니다. 오리진은 프로토콜(protocol), 도메인(domain), 포트(port)로 구성되어 있으며, 세 가지 중에 하나라도 다른 두 출처 간의 요청은 Cross-Origin Request인 것입니다.
(URL의 path, search, hash 부분이 다른 것은 "다른 출처"와 관련이 없습니다.)

CORS 정책 관련 오류 해결 방법

이제 상황에 따라 CORS 이슈를 해결하는 방법들을 알아보겠습니다.

1. 서버 컨트롤이 가능한 경우

정확히는 Cross-Origin Request에 대한 Response를 전송하는 서버를 컨트롤 할 수 있는 경우 사용할 수 있는 방법입니다.

응답 서버의 HTTP Response의 Access-Control-Allow-Origin Header 값에 해당 요청을 수락할 출처(Origin)들을 지정하여 CORS 정책 관련 문제를 해결할 수 있습니다.

Access-Control-Allow-Origin: <origin> | *

"*" 와일드 카드는 어떤 출처든 상관없이 리소스에 접근 가능하도록 허용합니다. (편리한 대신, 보안에 취약해집니다.)

이 방법을 사용한 경우, 브라우저는 서로 다른 출처들 간의 HTTP Request/Response가 사전에 상호합의된 것이므로 보안상 문제가 없다고 인지하고 CORS 정책 오류를 발생시키지 않게 됩니다.

다만, 인증 정보를 포함한 요청(Credentialed Request)인 경우 HTTP 헤더에 Access-Control-Allow-Credentials: true 를 추가해야 하며, Access-Control-Allow-Origin 헤더 값에 "*" 와일드카드 대신 출처를 직접 지정해야 합니다.

Credentialed Request
: HTTP cookies 또는 HTTP Authentication 정보가 포함된 요청

2. 서버 컨트롤이 불가능한 경우

다음은 Cross-Origin Request에 대한 Response를 전송하는 서버를 컨트롤 할 수 없는 경우입니다.

이런 경우에는 프록시 서버(Proxy Server)를 구축하여 요청을 우회시켜 CORS 정책 이슈를 해결할 수 있습니다.

위에서 이야기했던 것처럼, CORS는 브라우저 정책입니다. 그렇다면 브라우저를 끼지 않는 서버 간의 요청 및 응답에 대해서는 CORS 정책 문제가 당연히 발생하지 않습니다.

예를 들어, 요청을 보내는 서버를 A, 이에 따른 응답을 보내는 서버를 B로 가정하겠습니다.

프록시 서버를 두 서버 사이에 놓는다면, 이제 A 서버에서 B 서버로 직접 요청을 보내는 것이 아니라, A 서버는 프록시 서버로 요청을 보내고, 프록시 서버는 요청을 받으면 B 서버로 요청을 보내 데이터를 가져온 후, A 서버에서 보낸 요청에 대한 응답으로 해당 데이터를 보내는 과정이 이루어지는 것 입니다.

이제 프록시 서버는 "컨트롤이 가능한 서버"이므로, 위에서 작성한 1번 해결 방법을 통해 A 서버와 프록시 서버 간의 CORS 정책 문제를 해결할 수 있습니다.

위 작업을 위한 프록시 서버는 직접 구현 및 구축할 수도 있지만, cors-anywhere 라는 오픈 소스를 이용해 비교적 쉽게 만들 수 있습니다.


참고 자료

profile
함께하고 싶은 개발자, 이강현입니다:)

0개의 댓글