FrontEnd/Vue.js

CORS

M00NPANG 2023. 5. 16. 15:21
CORS (Cross-Origin Resource Sharing)

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

 


 

URL 구조

다른 출처간의 리소스 공유에 대해 알아보기 전 출처가 무엇인지 알기 위해서는 URL 구조가 어떻게 구성되는지를 알아야 한다. 서버의 위치를 의미하는 http://google.com과 과 같은 URL은 하나의 문자역 같지만 사진처럼 구성되어 있다.

출처(Origin)

Protocol, Host, Port가 포함된 주소로 브라우저 개발 도구의 콘솔 창에 lacation.origin을 실행하면 출처 확인이 가능하다.

같은 출처 : Protocol, Host, Port가 모두 동일한 경우
다른 출처 :Protocol, Host, Port 중 하나라도 다른 경우

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

웹 브라우저의 보안을 강화(XXS 또는 XSRF등의 보안 취약점을 노린 공격 방어)하기 위해 적용되는 중요한 보안 메커니즘으로, 웹 페이지나 스크립트가 동일한 툴러에서 로드된 리소스에만 접근할 수 있도록 제한한다.
출처는  Protocol(HTTP, HTTPS), Host(도메인) 및 Port로 정의한다. 
 
예를 들어, 웹 페이지가 "https://www.example.com"에서 로드되었다면 해당 페이지의 스크립트는 동일한 출처에서 로드된 리소스인 "https://www.example.com/images/image.jpg"에 접근할 수 있다. 그러나 다른 출처의 리소스인 "https://api.example.com/data"에 접근하려고 할 경우 동일 출처 정책에 의해 제한을 받게 된다.
 

Cross- Origin Request

웹 애플리케이션에서 동일 출처 정책을 우회하여 다른 도메인에 요청을 보내는 것을 의미
특정 시나리오에서는 다른 도메인에 있는 서비스 또는 데이터에 접근해야 할 때 크로스-출처 요청을 사용할 수 있다.
 


CORS 동작 방식

● 단순요청(Simple Request)
- 서버에서 받은 요청을 바로 보내는 방법
- 추가적인 프리플라이트 요청 X, 클라이언트는 서버로 직접 요청을 보내고, 서버는 허용된 도메인에서의 요청인 경우 적절한 CORS 관련 헤더를 응답으로 반환한다. 이로 인해 요청이 간단하게 처리되어 더 빠른 응답을 받을 수 있다.

JS에서 API를 요청할 때 브라우저와 서버의 동작을 나타내는 그림

- 브라우저는 다른 출처에 자신의 주소를 origin에 담아서 요청을 보낸다.
- 서버는 요청을 확인하고 다른 출처 주소에 접근이 가능하다는 access-control-allow-origin에 해당 주소를 담아서 결과를 리턴
access-control-allow-origin은 CORS 헤더의 중요 요소 중 하나로 어떤 요청을 허용할지 결정.
이 헤더 값은 하나의 출처가 될 수도 있고 "*"를 사용해 어떤 출처도 허용하도록 할 수 있음.
만약 서버가 이 헤더에 응답하지 않거나, 헤더 값이 요청의 출처와 일치하지 않는 도메인인 경우, 브라우저는 응답을 차단또한 요청한 출처가 서버의 access-conrol-allow-origin에 포함되어 있는 경우도 마찬가지!
 
- Simple request 조건
○  다음 중 하나의 요청 메서드

º  GET
º  HEAD
º  POST

○  아래의 헤더를 제외한 나머지는 사용하면 안된다.
※ 사용자 인증에 사용되는 Authorization 헤더 포함X.  까다로운 조건

º  Accept
º  Accept-Language
º  Content-Language
º  Content-Type (아래 추가 사항 유의)
º  DPR
º  Save-Data
º  Viewport-Width
º  Width

○  Content-Type 헤더는 다음의 값들만 허용
※ 많은 API들이 ontent-Type으로 application/json을 사용하기 때문에 지키기 어려운 조건 

º  application/x-wontent-Typeww-form-urlencoded
º  multipart/form-data
º  text/plain

○  비동기 요청 :XMLHttpRequest 객체의 withCredentials 속성이 false로 설정
○  동일 출처 요청: 동일 출처(Origin)에 있는 리소스에 대한 요청


● 프리플라이트(Preflight request)
- 서버에 예비 요청을 보내서 안전한지 판단한 후 요청을 보내는 방법
- 복잡한 요청 시나리오에서 사용되며, 추가적인 보안 검사 및 권한 확인을 위해 필요

-  OPTIONS 를 사용해 자신의 주소를 보낸다. 
 ○   요청 헤더 값

º  origin : 어디서 요청을 했는지 서버에 알려주는 주소
º  access-control-request-method : 실제 요청이 보낼 HTTP 메서드
º  access-control-request-headers : 실제 요청에 포함된 header

 
- 응답 헤더 값
○  access-control-allow-origin : 서버가 허용하는 출처
○  access-control-allow-methods : 서버가 허용하는 HTTP 메서드 리스트
○  access-control-allow-headers : 서버가 허용하는 header 리스트
○  access-control-max-age : 프리 플라이트 요청의 응답을 캐시에 저장하는 시간
 
- Preflight request 조건
○  심플 요청 조건을 충족하지 않을 때: 심플 요청의 조건을 모두 만족하지 못하는 경우 ex. 사용자 정의 헤더가 포함
○  크로스-출처 요청의 메서드가 GET, POST, HEAD가 아닐 때: PUT, DELETE 등의 다른 메서드를 사용하는 경우
○  Content-Type이 application/json 외의 다른 값일 때: application/json 이외의 Content-Type 값을 사용하는 경우


●  신용 요청(Credentialed Request)
- 쿠키, 인증 헤더, TLS 클라이언트 인증서 등의 신용정보와 함께 요청
- 다른 출처간 통신에서 좀 더 보안을 강화하고 싶을 때 사용하는 방법
- CORS 정책은 다른 출처 요청에 인증정보 포함을 허용하지 않으나 요청에 인증을 포함하는 플래그가 있거나 access-control-allow-credentials가 true로 설정 한다면 요청할 수 있다.

 
- Credentialed Request 옵션의 값

º  same-origin (기본값) : 같은 출처 간 요청에만 인증 정보를 담는다.
º  include : 모든 요청에 인증 정보를 담는다.
º  omit : 모든 요청에 인증 정보를 담지 않는다.

- 만약 same-origin 이나 include와 같은 옵션을 사용하여 리소스 요청에 인증 정보가 포함된다면, 브라우저는 다른 출처의 리소를 요청할 때 Access-Control-Allow-Origin만 확인하는 것이 아니라 다른 조건을 추가로 검사.
 
- 요청에 인증정보가 담겨있는 상태에서 다른 출처의 리소스를 요청하게 되면 브라우저는 CORS정책 위반 여부를 검사하는 룰에 다음 두가지를 추가.

º  Access-Control-Allow-Origin 에는 모든 요청을 허용하는*을 사용할 수 없으며, 명시적인 URL이어야 한다
º  응답 헤더에는 반드시 Access-Control-Allow-Credentials:true가 존재해야 한다

 


해결 방법

●  서버 측 CORS 설정 : 서버 측에서 CORS를 구성하여 허용된 도메인에서의 요청을 허용하는 방법
- 응답 헤더인 "Access-Control-Allow-Origin"을 설정 → 특정 도메인이나 모든 도메인에서의 요청을 허용
※ 관련 다른 헤더들도 설정 가능

1. Origin
 클라이언트가 요청을 보낸 출처(Origin)를 나타내는 헤더
 브라우저는 이 헤더를 요청에 자동으로 포함
2. Access-Control-Allow-Origin
 서버가 허용하는 출처(Origin)를 나타내는 헤더
서버 응답에서 설정되며, 특정 도메인이나 모든 도메인("*")을 허용 가능
클라이언트는 이 헤더를 확인하여 요청이 허용되는 출처인지 확인
3. Access-Control-Allow-Methods
 서버가 허용하는 HTTP 메서드를 나타내는 헤더
4. Access-Control-Allow-Headers
 서버가 허용하는 사용자 정의 헤더를 나타내는 헤더
 서버 응답에서 설정되며, 클라이언트는 이 헤더를 확인하여 허용된 메서드로 요청 수신 가능
5. Access-Control-Allow-Credentials
 서버가 클라이언트의 인증 정보(쿠키, 인증 헤더 등)를 허용하는지 여부를 나타내는 헤더
 이 헤더를 "true"로 설정하면 인증 정보를 포함한 요청이 허용
6. Access-Control-Expose-Headers
 클라이언트가 액세스할 수 있는 추가적인 응답 헤더를 나타내는 헤더
 서버에서 클라이언트가 접근해도 안전한 헤더를 지정
7. Access-Control-Max-Age
 프리플라이트 요청의 결과를 캐싱할 시간을 나타내는 헤더
 이 헤더를 설정하면 브라우저는 지정된 시간 동안 프리플라이트 요청을 반복하지 않고 캐시된 결과를 사용

●  프록시 서버 사용
- 클라이언트는 프록시 서버에 요청을 보내고, 프록시 서버는 해당 요청을 서버로 전달하며 CORS 관련 헤더를 처리
- 클라이언트와 서버 간의 통신은 동일 출처로 이루어지기 때문에 CORS 문제가 발생X
- 서버 측에서 CORS를 직접 구성할 수 없거나 수정할 수 없는 경우에 유용
 
●  JSONP(JSON with Padding) 사용
-  CORS 문제를 우회하기 위한 대안.
-  JSONP는 스크립트 태그를 사용하여 서버로부터 JSON 데이터를 동적으로 로드하는 방법.
-  서버는 JSON 데이터를 콜백 함수로 래핑하여 응답.
-  클라이언트는 스크립트 태그를 생성하고 콜백 함수를 정의하여 데이터를 수신.
JSONP는 CORS 문제를 우회할 수 있지만, 보안상의 이유로 몇 가지 제한 사항이 있으므로 주의.
 
●  CORS 라이브러리 또는 프레임워크 사용
 

'FrontEnd > Vue.js' 카테고리의 다른 글

호이스팅(Hoisting)  (1) 2023.05.18
PWA란?  (0) 2023.05.16
node.js 환경 vs 브라우저 환경  (1) 2023.05.07
Vue.js vs React  (1) 2023.05.07
REST API, RESTFUL API  (0) 2023.05.07
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함