TECH

프론트개발시 CORS 오류와 해결방법!

ssund 2022. 3. 20. 14:16

이번에 작업을 하면서 CORS 오류를 제대로 경험했다!! 정말 힘든 시간이었던 이번 작업

기능 개발보다 CORS오류를 해결하는 시간이 더 오래 걸렸다...

다음에는 당황하지 않기 위해 CORS에 대해 정리하는 시간을 가지려고 한다!

 

CORS는 무엇인가? 

CORS(Cross-Origin Resource Sharing)는 교차 출처 리소스 공유라고 한다. 

HTTP 헤더를 사용해서 다른 출처에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제라고 한다.

 

언제 CORS현상이 나올까 

호스트, 프로토콜, 포드가 다른 경우에 CORS현상이 발생된다. 

https://shopping.naver.com:80/home/p/index?sort=asc&page=2#tab2

프로토콜                호스트                포트번호        패스                            쿼리스트링          프래그먼트

 

 

왜 CORS 가 필요할까?

CORS이슈가 없으면 개발하기 정말 편할 것 같은데 CORS가 있는 이유는 무엇일까? 

웹에 있는 코드들은 누구나 확인할 수 있고 암호화되어있지 않아서 개발자 도구로 언제든지 확인이 가능해서

CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting)을 사용하여 사용자의 정보에 접근할 수 있어서 

보안 이슈가 나타난다. 

 

CSRF, XSS 는 무엇인가?

CSRF 공격(Cross Site Request Forgery)은 웹 애플리케이션 취약점 중 하나로 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 만드는 공격입니다.

크로스 사이트 스크립팅(Cross Site Scripting, XSS)은 공격자가 상대방의 브라우저에 스크립트가 실행되도록 해 사용자의 세션을 가로채거나, 웹사이트를 변조하거나, 악의적 콘텐츠를 삽입하거나, 피싱 공격을 진행하는 것을 말합니다. 

 

CORS는 브라우저에서 판단한다.

출처를 비교하는 로직은 브라우저에 구현되어있는 스펙이다. 

브라우저를 통하지 않고 서버 간 통신을 할 때에는 정책이 적용되지 않는다. 

리소스 요청 에러가 나도 서버에서는 정상응답이 나오기 때문에 정확히 확인할 수 없다.

 

CORS는 어떻게 동작 하나요

http 프로토콜을 사용하여 요청을 보내고 

브라우저는 요청 헤더에 origin 필드에 요청을 보내는 출처를 함께 담아 보낸다.

서버가 응답할 때 응답 헤더의 access-control-allow-origin 이라는 값에 허용된 출처를 내려주고 

응답을 받은 브라우저가 유효한 origin인지를 확인

 

Preflight Request 프리플라이트 

일반적으로 하는 요청 시나리오이다. 브라우저가 예비 요청, 본 요청 2번으로 서버에 전송한다.

예비 요청은 http메서드 중 options메소드가 사용된다. 본요청을 보내기전에 안전한지 확인하는 요청이다.

예비요청을 하고 나면 응답받는 access-control-allow-origin를 브라우저가 확인하고 

요청한 origin이 안전한지 확인 후 본요청을 하고 서버로부터 응답을 받을 수 있다.

브라우저는 최종적으로 서버로 받은 응답을 자바스크립트로 넘겨준다.

 

예비요청에서 어떤 메소드와 어떤 타입을 사용할 것인지 미리 알려준다.

Access-Control-Request-Headers: content-type
Access-Control-Request-Method: GET

 

Simple Request

Preflight Request와 로직은 동일하지만 예비요청이 없는것이 다른다

심플리퀘스트를 하기위해서는 특정 조건을 만족해야 한다. 업무 중에서 특정 조건을 만족하는 요청을 찾기는 힘들 것 같다.

1. 요청의 메소드는 GET, HEAD, POST 중 하나여야 한다.
2. Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안 된다.
3. 만약 Content-Type를 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용된

 

대부분의 HTTP API는  text/xml이나 application/json를 가지도록 설계하기 때문에 심플리퀘스트를 적용하기 힘들 것 같다.

 

CORS 해결방법

1. Access-Control-Allow-Origin 세팅하기

서버에서 Access-Control-Allow-Origin헤더에 세팅해주기!

Access-Control-Allow-Origin: * 설정해두면 모든 출처를 허용하지만 보안적인 이슈가 크기 때문에 사용하지 않는 것을 추천한다. 

 

2. webpack dev server 프록싱 설정하기 

프론트 개발을 할 때 npm플러그인을 통해서 개발 환경에서만 교차출처 리소스에 대해 예외처리를 할 수 있다. 

이 방법은 개발이 끝나고 배포가 될 때 또 같은 이슈가 난다. 

 

 

참고사이트

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

https://evan-moon.github.io/2020/05/21/about-cors/