[CS] 개발하며 한번쯤은 만나는 CORS 오류 원인과 해결 방법 정리

개발하며 CORS 빨간 에러를 한번도 안 만나본 사람은 없을 것이다 

그런데 알고보면 CORS는 문제가 없다..@@ 오히려 문제 해결 방법인 🥹


CORS (Cross Origin Resource Sharing) : 교차 출처 리소스 공유

이름과 같이 다른 Origin으로 리소스를 요청했을 때 발생한다

 

다른 도메인으로 요청을 보내면 cross-origin HTTP 요청에 의해 요청 되며, 요청 헤더에 Origin 필드를 추가한다

하지만 대부분의 브라우저들은 보안상의 이유로 cross-origin 요청을 제한한다

 

이때 보이는 보안상의 이유가 원인이다 

 

SOP (Same Origin Policy) : 동일 출처 정책

해당 정책은 브라우저의 기본 보안 정책 중 하나로,  웹 브라우저가 특정 origin의 문서나 스크립트가 다른 출처의 리소스와 상호작용을 제한하는 정책이다

 

여기서 동일 출처란, protocol + host + port 조합이 동일한 웹사이트를 의미한다

만약 localhost에서 서로 다른 포트를 사용하는 것 또한 다른 출처가 된다

origin = protocol + host + port

 

만약 다른 출처의 문서, 스크립트가 자유롭게 리소스를 공유할 수 있다면 악의적인 목적으로 

크로스 사이트 스크립팅(XSS), 크로스 사이트 요청 위조(CSRF)과 같은 방법을 통해 사용자 개인 정보를 가로챌 수 있다

 

이러한 경우를 방지하기 위해 SOP 정책으로 서로 다른 origin일 경우, 리소스 교환이 되지 않도록 하는 것이다

 

CORS의 기본 동작

1. 클라이언트에서 HTTP 요청 헤더에 Origin 을 담아 서버에 보낸다

2. 서버는 응답 헤더에 Access-Control-Allow-Origin 을 담아 클라이언트에 보낸다

3. 클라이언트는 Origin === Access-Control-Allow-Origin 인지 비교한다

    - ok = 응답 데이터 받아옴

    - ❌ = 응답 데이터 버림 + CORS 에러

 

CORS의 3가지 작동 방법

1. 사전 요청 (preflight)

CORS 요청에는 simple request / preflight request , 이렇게 2가지가 있다

 

일반적으로는 simple request 로 진행된다

해당 방법은 서버로 요청은 다 보내지만, SOP로 통과를 못하면 응답을 받아오지 못한다

 

preflight request는 요청을 보내기 전에 미리 확인을 하는 방법이다

OPTIONS 메소드를 이용해 실제 요청 전에 허가를 받은 뒤, ok가 되면 브라우저에서 자동으로 실제 요청을 보낸다

 

✨ 사전 요청이 필요한 경우

1. 사용하는 메소드가 GET, POST, HEAD가 아닌 경우 (= PUT, DELETE, OPTIONS)

2. 특정 HTTP 헤더를 사용하는 경우
    - 표준 헤더(Content-Type, Accept 등)가 아닌, 커스텀 헤더를 사용하는 경우
    - Content-Type이 application/x-www-form-urlencoded, multipart/form-data, text/plain이 아닌 경우

3. Credentials(쿠키나 인증 관련 정보) 사용시
    - 클라이언트가 요청에 인증 정보를 포함하는 경우 (withCredentials : true)

 

2. 프론트에서 proxy 서버 사용

클라이언트 ➡️ proxy 서버 ➡️ 실제 서버

 

위와 같은 방법으로 해결할 수 있다

CORS 문제는 브라우저의 보안 정책으로 발생하는 문제이므로, 서버를 통해 보내지는 요청은 제한되지 않는다

 

프록시 서버는 클라이언트의 요청을 받아 서버로 전달하고, 응답을 받아 클라이언트에 전달하는 중간다리 역할을 하는 것이다

 

 

3. 서버에서 접근 허용 (= CORS 설정)

해당 방법이 바로 CORS를 설정하는 것이다

서버에서 Access-Control-Allow-Origin에 접근을 허용할 origin을 입력해두어서, 일종의 화이트리스트를 만드는 것이다

 

즉, 요청 헤더의 Origin === 응답 헤더 Access-Control-Allow-Origin 이면 안전한 요청으로 간주해서 응답데이터를 가져오게 되는 것이다

 

 

 

참고자료

https://lo-victoria.com/introduction-to-cross-origin-resource-sharing-cors

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

https://github.com/baeharam/Must-Know-About-Frontend/blob/main/Notes/security/sop.md