04. 기술면접 - 네트워크 - CORS
공부목적으로 다른 블로그의 글을 그대로 따라치면서 작성되었습니다. 저작권 문제 시, 비공개 처리하겠습니다
개념
- CORS (Cross Origin Resource Sharing)
- 웹 서버에게 보안 cross-domain 데이터 전송을 활성화 하는 cross-domain 접근 제어권을 부여한다
- 배경
- 처음 전송되는 리소스의 도메인(request origin)과 다른 도메인(response orign)으로부터 리소스가 요청 될 경우
corss-origin HTTP 요청에 의해 요청됨
- 보안 상의 이유로, 브라우저들은 스크립트 내에서 초기화되는 cross-origin HTTP 요청을 제한한다
- 예를 들면 XMLHttpRequest 는 same-orgin 정책을 따르기에 XMLHttpRequest 를 사용하는 웹 애플리케이션은
자신과 동일한 도메인으로 HTTP 요청을 보내는 것 만 가능했다
- 순수 Ajax ( XMLHttpRequest ), Jquery Ajax ( $.ajax ), Promise 기반 Ajax (Axios)
- 웹 애플리케이션을 개선시키기 위해, 개발자들은 브라우저 벤더사들에게 XMLHttpRequest 가
cross-domain 요청을 할 수 있도록 요청했고 이에 따라 CORS 가 생겼다
- 정확히 기존에는 <img src> 라던가 <link href> 라던가 에서는 이미 CORS 를 지원하고 있었고 <script> 단에서도
CORS 를 허용하게 해달라는 요청이 생겨 서버에서 허용할 때에만 script 에서도 CORS 가 가능해진 것이다
- 과정
- CORS 요청 시에는 미리 OPTIONS 주소로 서버가 CORS 를 허용하는 지 물어본다
- 이 때 Access-Control-Request-Method로 실제로 보내고자 하는 메서드를 알리고,
- Access-Control-Request-Headers 로 실제로 보내고자 하는 헤더를 알린다
- Allow 항목들은 Request 에 대응되는 것으로, 서버가 허용하는 메서드와 헤더를 응답하는 데 사용된다
- Request 랑 Allow 가 일치하면 CORS 요청이 이루어진다
CORS 요청 종류
- Simple Request 와 Prefligth Request
- Credential Request 와 Non-Credential Request
종류는 위와같이 4가지가 존재하며 4가지 방식 중 해당하는 방식으로 서버에 요청을 날리므로, 프로그래머가 목적에 맞는 방식을 선택하고 그 조건에 맞게 코딩해야 합니다
Simple Request (간단 요청)
: 클라이언트가 서버에 1번 요청하고, 서버도 클라이언트에게 1번 회신하는 것으로 처리가 종료됩니다
[조건]
1. GET, HEAD, POST 방식
2. POST 방식5인 경우 Content-type 이 아래 셋 중의 하나여야 한다
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
3. 커스텀 헤더(내부적인 헤더가 아닌 직접 만든 헤더) 를 전송하지 말아야 한다
Prefligth Request (예비 요청)
: Simple Request [조건] 에 해당하지 않으면 브라우저는 Preflight Request 방식으로 요청
: 먼저 서버에 예비요청(Prefligth Request) 을 보내고 서버는 예비 요청에 대해 응답 하고, 그 다음에
본 요청 (Actual Request) 를 서버에 보내고, 서버도 본 요청에 응답합니다
: 2번 요청 2번 회신
: 예비요청을 보내기 위해서는 OPTIONS 메소드를 활용니다
[조건]
1. GET, HEAD, POST, PUT, PATCH, DELETE, OPTION 등 방식
2. Content-type 에서 application/xml 과 같은 다양한 type 사용
3. 다양한 커스텀 헤더 사용
즉, API 서버에 요청을 보낼 때는 OPTIONS 로 체크한 다음 서버에서 Access Control Allow-메소드명 등을 응답 받은 뒤
현재 보내는 본 요청(GET|POST 등)이 응답 받은 Allow 에 조건에 부합하면 본 요청을 서버에 날린 후 응답을 받게 된다
axios 나, jquery 등 라이브러리 내에서 그런 역할을 처리한건지 아니면 자바스크립트 내장으로 인식하고 있어서 자동으로 option 을 해주는 지는 안찾아봐서는 모르겠다 둘 중 1가지 방법으로 option 을 요청하지않을까 생각된다
Request With Credential (자격 증명=인증 이 포함된 요청)
: HTTP Cookie 와 HTTP Authentication 정보를 인식할 수 있게 해주는 요청이다
const xhr = new XMLHttpRequest() 를 이용하여 요청시 xhr.withCredentials = true 를 지정해서 Credential 요청을 보낼 수 있고, 서버는 Response Hanlder 에 반드시 Acces-Control-Allow-Credentails : true 를 포함해야 하고, Access-Control-Allow-Origin 헤더의 값에는 * 은 피해야하고 구체적인 http://foo.origin 과 같은 구체적인 도메인이 와야한다
Credentails 옵션은 true 로 줬는 데 Control-Allow-Orign 의 값을 *로 주면 에러가 발생합니다
그림은 아까위에 Spring 코드를 참고하시면 됩니다
Request without Credential (자격 증명=인증 이 포함안 된 요청)
CORS 요청은 기본적으로 Non-Crendential 요청이므로 xhr.withCredentails = true 를 지정하지 않으면 Non-Crendential Rquest 입니다
// 자바스크립트 코드 - 클라이언트에서 서버에 요청하려고 할 때 이런식으로 속성을 정의합니다
const xhr = new XMLHttpRequest()
xhr.withCredentials = true
참고로 클라이언트에서 withCredentials 를 true 를 준다하여도 서버에서 credentials 를 false 를 줬다면 응답(response) 는 브라우저에 의해 무시되어
다음 본 요청을 하게 되는 경우 Request With Crendentail 을 보낼 수 없게 됩니다
-> 이게 인증이 포함이 안된 상태로 본 요청이 나가는 지 아니면 본 요청 자체가 안나가는 지는 시도하지않아서 모르겠습니다
결론
CORS 를 쓰면 AJAX 로도 Same Origin Policy 의 제약을 넘어 다른 도메인의 자원을 사용할 수 있음
CORS 를 사용하려면 클라이언트에서는 Access-Control-** 류의 HTTP Header 를 서버에 보내야 하고,
서버도 Acces-Control-** 류의 HTTP Header 를 클라이언트에 회신하게 되어 있어야 한다
'∞. 기술 면접 > 2. 네트워크' 카테고리의 다른 글
06. 기술면접 - 네트워크 - 쿠키, 세션, 로컬 스토리지, 세션 스토리지 (0) | 2021.09.30 |
---|---|
05. 기술면접 - 네트워크 - GET 과 POST (0) | 2021.09.30 |
03. 기술면접 - 네트워크 - HTTP 와 HTTPS 프로토콜 (0) | 2021.09.29 |
02. 기술면접 - 네트워크 - TCP & UDP (0) | 2021.09.28 |
01. 기술면접 - 네트워크 - OSI 7 계층 (0) | 2021.09.27 |
댓글
이 글 공유하기
다른 글
-
06. 기술면접 - 네트워크 - 쿠키, 세션, 로컬 스토리지, 세션 스토리지
06. 기술면접 - 네트워크 - 쿠키, 세션, 로컬 스토리지, 세션 스토리지
2021.09.30 -
05. 기술면접 - 네트워크 - GET 과 POST
05. 기술면접 - 네트워크 - GET 과 POST
2021.09.30 -
03. 기술면접 - 네트워크 - HTTP 와 HTTPS 프로토콜
03. 기술면접 - 네트워크 - HTTP 와 HTTPS 프로토콜
2021.09.29 -
02. 기술면접 - 네트워크 - TCP & UDP
02. 기술면접 - 네트워크 - TCP & UDP
2021.09.28