네트워크 - 쿠키, 교차 출처 리소스 공유(CORS)

이정인·2022년 2월 8일
1
<기초부터 완성까지 프론트엔드>를 읽고 정리한 내용입니다.

쿠키

HTTP 쿠키는 서버가 사용자의 웹 브라우저에 전송하는 기록 정보 파일을 의미함. 상태가 없는 HTTP에서 브라우저는 쿠키 정보를 기록하여 동일한 서버에 재요청 시 저장된 쿠키 정보를 같이 전송함. 공개된 정보이기 때문에 보안에 취약함. 현재는 웹 스토리지 같은 정보를 저장할 수 있는 저장소가 추가로 생겨서 사용성에 맞춰 선택할 수 있음. 이름-값 쌍으로 정보를 기록하며 쿠키의 만료 기간, 도메인, Secure, HttpOnly 등의 정보를 기록함

서버에서 전송된 HTTP 응답의 Set-Cookie 헤더로 쿠키를 만들기

HTTP/ 1.1 200 OK
Content-type: text/ html
Set-Cookie: cookie1=value1
Set-Cookie: cookie2=value2

응답을 통해 두 개의 쿠키 속성을 생성하여 저장

GET/ page.hmlt HTTP 1.1
Host: ...
Cookie: cookie1=value1; cookie2=value2

이후 서버로 전송되는 모든 요청에 해당 쿠키 값을 회신

속성

  • 쿠키 삭제

    쿠키는 세션이 종료될 때 삭제된다. Expries 속성에 날짜가 적혀있거나 Max-age에 기간(초)가 명시되어 있다면 그 이후에 삭제되며 Max-age가 우선

  • 쿠키 스코프

    Domain과 Path 속성은 쿠키에 접근할 수 있는 도메인과 URL 경로를 설정할 수 있음

    • Domain가 명시되어 있지 않을 경우 : 현재 문서 위치를 기준으로 서브 도메인을 포함
    • Path를 지정할 수 경우 : 해당되는 URL 경로와 서브 디렉토리 경로에서 쿠키에 접근할 수 있음
  • Secure, HttpOnly

    쿠키는 기본적으로 프로토콜이 아닌 도메인을 기준으로 판단. Secure 속성을 사용할 경우 HTTPS로 통신하는 경우에만 쿠키가 전송됨

    HttpOnlys는 클라이언트 측에서 쿠키를 사용할 수 없게함. document.cookie와 같이 클라이언트 측에서 자바스크립트를 사용하여 쿠키에 접근하는 것을 막음

document.cookie

현재 접속한 사이트에 관련된 쿠키 정보를 알 수 있다.

document.cookie="name=jungin; path=/;"

쿠키 하나가 차지하는 용량은 4KB이며 브라우저에 따라 허용하는 쿠키는 약 20개 내외임

교차 출처 리소스 공유 (Cross Origin Resource Sharing, CORS)

두 URL의 프로토콜, 포트, 호스트가 모두 같을 때 동일 출처라 부르게 됨.

ex) http://a.test.com:80/docs
=> http://a.test.com:80/write  동일 출처 (o)
=> http://b.test.com:80/tutorial 동일 출처 (x) 호스트가 다름

동일 출처 정책 (Same Origin Policy, SOP)은 한 출처로부터 로드된 문서나 자바스크립트가 다른 출처의 자원과 상호작용하는 것을 제한하는 보안 방식이다. 두 URL의 출처(Origin)가 다른 경우 별도의 처리 없이 API 서버의 응답을 수신할 수 없다.

동일 출처 정책은 브라우저의 보안을 위해 잠재적으로 위험이 있는 문서의 접근을 허용하지 않는다. 과거에는 웹 서버에서 요청을 처리해 결과를 정적인 페이지로 내려줬기 때문에 큰 문제가 되지 않았지만 외부 API 서비스를 활용하거나 클라이언트와 API 서버를 분리하여 웹 사이트를 만드는 등 웹 사이트의 기능과 역할이 많아지면서 이러한 정책이 문제가 되기 시작했다.

이를 해결하기 위해서 허용된 출처를 서버에 알려줄 수 있는 HTTP 헤더가 추가되었으며 CORS는 이 헤더를 이용하여 애플리케이션에서 다른 출처의 리소스에 접근할 수 있도록 권한을 수 있다.

CORS는 요청을 보낸 헤더의 Origin 필드와 서버가 보내준 Access-Control-Allow-Origin을 비교해 이 응답이 유효한지 브라우저에서 판단 후 유효하지 않을 경우 해당 응답을 에러 처리한다. 가장 일반적으로 많이 사용되는 시나리오는 사전 요청(preflighted) 방식이다.

단순 요청 (Simple requests)

아래의 조건을 모두 충족하는 요청

다음 중 하나의 메서드

유저 에이전트가 자동으로 설정 한 헤더외에, 수동으로 설정할 수 있는 헤더는 오직

Fetch 명세에서 “CORS-safelisted request-header”로 정의한 헤더

뿐입니다.

Content-Type

헤더는 다음의 값들만 허용됩니다.

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

요청에 사용된 XMLHttpRequestUpload 객체에는 이벤트 리스너가 등록되어 있지 않습니다. 이들은 XMLHttpRequest.upload 프로퍼티를 사용하여 접근합니다..

요청에 ReadableStream 객체가 사용되지 않습니다.

클라이언트와 서버 간에 간단한 통신을 하고, CORS 헤더를 사용하여 권한을 처리함

브라우저는 서버로 전송하는 내용을 살펴보고 서버의 응답을 확인한다.

Access-Control-Allow-Origin: * 는 모든 도메인에서 접근할 수 있음을 의미

사전 요청 방식 (Preflighted requests)

사전 요청 방식은 Cross-site 요청이 유저 데이터에 영향을 줄 수 있기 때문에 OPTIONS HTTP 메서드를 이용해 실제 요청을 전송하기 전 안전한 요청인지 허가를 받은 뒤 실제 요청을 보내는 방식이다. 일반적으로 브라우저에서 자동으로 전송한다.

브라우저에서 실제 POST 요청을 보내기 전 사전 요청을 보내 해당 도메인의 POST 메서드를 허용하는지 물어본다. Access-Control-Allow-Origin은 서버에서 허용하는 출처가 무엇인지 알려주며 브라우저는 이를 이용해 리소스에 접근할 수 있는지 판단한다.

서버가 해당 요청을 허용할 경우 Access-Control-Allow-Methods 필드에 허용하는 메서드가 나타나며 Access-Control-Allow-Origin 필드에 허용하는 출처에 대해 나타난다.

사전 요청이 마무리 되면 실제 요청을 보낸 뒤 응답을 받는다.

인증 정보를 포함한 요청

브라우저에서 제공되는 XMLHTTPRequest나 fetch()는 출처가 다를 경우 브라우저의 쿠키나 인증 정보를 헤더에 담지 않는다. 만약 인증 정보를 요청에 담아 보내고 싶다면 credentials 옵션을 변경해야한다. 총 3개의 값을 가질 수 있다.

  • same-origin : 동일 출처라면 보냄
  • omit : 동일 출처 여부와 상관없이 항상 쿠키를 전송하지 않음
  • include: 교차출처라도 보냄

credentialsinclude일 경우 서버에서 Access-Control-Allow-Origin가 와드 카드(*)로 설정했다면 요청이 실패함. 명확하게 어떤 출처를 신뢰하는지 확인하기 위한 추가적인 안전 조치임. 따라서 와일드 카드가 아닌 명확한 URL을 명시해야한다.

해당 요청이 성공적으로 처리된다면 응답에는 Access-Control-Allow-Credential이 true로 되어 반환되며, 해당 헤더가 포함되지 않는다면 응답은 무시된다.

한줄 요약

CORS는 해당 어플리케이션에서 다른 출처의 리소스에 접근할 수 있도록 추가적인 HTTP 헤더를 사용하여 권한을 주는 방식이다.

참고

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

0개의 댓글