[WEB] CORS

minidoo·2021년 5월 19일
0

WEB

목록 보기
5/8
post-thumbnail

1. CORS란?

Cross-Origin Resource Sharing

HTTP 헤더를 사용하여 브라우저가 한 출처에서 실행중인 웹 애플리케이션에 선택된 엑세스 권한을 부여하도록 하는 메커니즘

2. CORS 문제 발생 원인

2-1. 도메인이 다를 때

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을 확인해야 한다.

2-2. https에서 http로 통신할 때

이는 보안과 관련 있다.
시큐어된(https) 홈페이지에서 http 평문 통신을 시도할 경우 발생하는데, 이 경우엔 같이 보안 통신 해줘야 한다.

반대의 경우에는 발생하지 않는다.

3. CORS 해결 방법

3-1. 동일한 도메인 사용

동일한 도메인을 사용하면 애초에 문제가 발생하지 않는다.

3-2. HTTP 헤더 설정

Simple Request

기본적으로 ① 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

Preflighted Requests(사전 통신)은 실제 요청과 응답을 주고 받기 전에 요청하는 쪽이 CORS 권한이 있는지 사전 검사를 한 후 브라우저에서 실제 요청을 보낸다.

사전 검사는 HTTP 메소드인 OPTIONS 를 이용한다.

Preflighted 요청은 단순히 Access-Control-Allow-Origin 헤더를 추가하는 것만으로는 해결할 수 없다.

OPTIONS 방식의 헤더에는 Access-Control-Request-HeadersAccess-Control-Request-Methods에 각각 authorization과 GET으로 요청한다.

응답 헤더에는 Access-Control-Allow-Headers 에 요청한 authorization이 들어 있고, Access-Control-Allow-Methods 에 GET이 들어있다.

즉, 요청하는 쪽의 CORS 권한이 있다는 것이다.
만약 각각에 원하는 값이 들어있지 않으면 CORS 문제가 발생하는 것이다.

3-3. 그 외 방법들

직접 서버의 헤더를 설정할 수 있는 상황이 아니라면,
프록시 서버JSONP를 사용한다.

Proxy Server

프론트엔드 개발자들이 많이 사용하는 방식으로 브라우저와 서버 통신의 중간에서 정보 교환을 도와주는 서버를 의미한다. 프록시 서버는 헤더를 설정하는 역할을 해주며 Access-Control-Allow-Origin: *를 담아 응답해준다.

속도가 느려지는 단점이 있다.

JSONP

JSONP은 Legacy라 불리는 예전 형태의 API들이나 통신을 해야할 경우만 사용한다.

CORS 컨트롤을 통해서 데이터를 핸들링하는 것이 최적의 방법이지만 직접 서버의 헤더를 설정할 수 있는 상황이 아닌 경우, Proxy(서버)를 거치지 않고 데이터 규약을 정해서 처리할 수 있는 방법이다.

audio, img, link, script, video와 같은 태그에 있는 crossOrigin 속성은 Preflighted 요청 없이도 CORS를 가능하게 한다. 특정 element에서는 crossorigin 속성으로 CORS를 세팅할 수 있다.

이를 이용하여 특정 주소를 script 태그에 담아 처리하면 해결할 수 있다.

4. Credential Reuest

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

0개의 댓글