Cross-Origin Resource Sharing
HTTP 헤더를 사용하여 브라우저가 한 출처에서 실행중인 웹 애플리케이션에 선택된 엑세스 권한을 부여하도록 하는 메커니즘
domain-a.com 이라는 도메인에서 domain-b.com 으로 요청을 보낼 때 문제가 발생한다.
같은 도메인 간의 통신은 문제가 되지 않지만, 다른 도메인 간의 데이터 통신은 보안상 문제가 발생할 수 있다.
CORS
는 브라우저가 유발시킨다.
만약, 브라우저에서 서버로 GET 방식 요청을 했을 때 200(정상) 응답을 받았다고 한다. 하지만 CORS의 발생 원인은 브라우저이기 때문에 서버와의 정상 통신 이후 문제가 발생할 수 있다.
https://miniddo.com:3000/product?a=1
protocol://host:port/pathname?query
도메인은 protocol://host:port
을 말한다.
브라우저에서 도메인은 Origin
이라는 헤더 객체에 들어있다.
따라서 도메인과 함께 Header
을 확인해야 한다.
이는 보안과 관련 있다.
시큐어된(https) 홈페이지에서 http 평문 통신을 시도할 경우 발생하는데, 이 경우엔 같이 보안 통신 해줘야 한다.
반대의 경우에는 발생하지 않는다.
동일한 도메인을 사용하면 애초에 문제가 발생하지 않는다.
기본적으로 ① GET, HEAD, POST를 허용한다.
Preflighted Requests는 발생하지 않지만, CORS 문제는 발생할 수 있다.
이때, Access-Control-Allow-Origin
를 허용(*
)하면 해결된다.
② Accept, Accept-Language, Content-Language, Content-Type
③ Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data, text/plain의 값들만 허용된다.
Preflighted Requests(사전 통신)은 실제 요청과 응답을 주고 받기 전에 요청하는 쪽이 CORS 권한이 있는지 사전 검사를 한 후 브라우저에서 실제 요청을 보낸다.
사전 검사는 HTTP 메소드인 OPTIONS
를 이용한다.
Preflighted 요청은 단순히 Access-Control-Allow-Origin
헤더를 추가하는 것만으로는 해결할 수 없다.
OPTIONS 방식의 헤더에는 Access-Control-Request-Headers
과 Access-Control-Request-Methods
에 각각 authorization과 GET으로 요청한다.
응답 헤더에는 Access-Control-Allow-Headers
에 요청한 authorization이 들어 있고, Access-Control-Allow-Methods
에 GET이 들어있다.
즉, 요청하는 쪽의 CORS 권한이 있다는 것이다.
만약 각각에 원하는 값이 들어있지 않으면 CORS 문제가 발생하는 것이다.
직접 서버의 헤더를 설정할 수 있는 상황이 아니라면,
프록시 서버나 JSONP를 사용한다.
프론트엔드 개발자들이 많이 사용하는 방식으로 브라우저와 서버 통신의 중간에서 정보 교환을 도와주는 서버를 의미한다. 프록시 서버는 헤더를 설정하는 역할을 해주며 Access-Control-Allow-Origin: *
를 담아 응답해준다.
속도가 느려지는 단점이 있다.
JSONP은 Legacy라 불리는 예전 형태의 API들이나 통신을 해야할 경우만 사용한다.
CORS 컨트롤을 통해서 데이터를 핸들링하는 것이 최적의 방법이지만 직접 서버의 헤더를 설정할 수 있는 상황이 아닌 경우, Proxy(서버)를 거치지 않고 데이터 규약을 정해서 처리할 수 있는 방법이다.
audio, img, link, script, video
와 같은 태그에 있는 crossOrigin 속성은 Preflighted 요청 없이도 CORS를 가능하게 한다. 특정 element에서는 crossorigin
속성으로 CORS를 세팅할 수 있다.
이를 이용하여 특정 주소를 script
태그에 담아 처리하면 해결할 수 있다.
HTTP Cookie와 HTTP Authentication 정보를 인식할 수 있게 해주는 요청
fetch 통신
요청 시 {credentials : "include"}
를 보내면
응답 헤더에는 Access-Control-Allow-Credentials: true
가 설정되어 있어야 한다.
credentials은 access-control-allow-origin
가 와일드 카드(*
)로 설정되어 있으면 동작하지 않는다. 명시적으로 통신하고자 하는 특정 도메인을 넣어준다.
( 디폴트는 {credentials : "same-origin"}
로 설정되어 있다. )
xmlhttprequest
도메인이 다른 http 통신에서는 request header에 쿠키가 자동으로 들어가지 않다. 쿠키가 없으면 서버는 클라이언트를 인식할 수 없기 때문에 직접 쿠키를 넣어주어야 한다.
(Front) withCredentials : true
(Server) Access-Control-Allow-Credentials : true
따라서 프론트와 서버에 위처럼 넣어주면 쿠키가 포함되는 것을 볼 수 있다. 이때, Access-Control-Allow-Origin : "*"
인 경우는 fetch 통신과 마찬가지로 origin에 특정 도메인 값을 넣어준다.
https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://kosaf04pyh.tistory.com/152
https://velog.io/@logqwerty/CORS