쿠키

chaeruru·2021년 10월 23일
1

쿠키란?

쿠키는 브라우저에 저장되는 작은 크기의 문자열로 HTTP 프로토콜의 일부이다. HTTP 프로토콜은 Stateless이다. 즉, 서버가 클라이언트의 상태를 보존하지 않는다.

그럼 각각의 클라이언트를 식별해야 하는 경우(로그인)는 어떻게 해결할까? 이때 쿠키를 사용하여 해결할 수 있다.

  1. 사용자가 로그인하면 서버는 HTTP 응답 헤더의 Set-Cookie 에 담긴 세션id 정보를 사용해 쿠키를 설정한다.
  2. 사용자가 동일 도메인에 접속하려고 하면 Cookie HTTP 헤더안에 설정된 쿠키를 포함하여 요청을 보낸다.
  3. 서버는 브라우저가 보낸 요청 헤더의 정보(세션 id)를 읽어 사용자를 식별한다.

이렇게 쿠키는 클라이언트 식별과 같은 인증에 가장 많이 쓰인다.

이외에도 쿠키는 다음과 같은 경우 사용된다.

  • 세션 관리
    • 서버에 저장해야 할 로그인, 장바구니, 게임 스코어 등의 정보 관리
  • 개인화
    • 사용자 선호, 테마 등의 개인 설정
  • 트래킹
    • 사용자의 행동을 기록하고 분석

쿠키 읽기, 쓰기

읽기

document.cookie 를 이용하면 브라우저에서 쿠키를 접근할 수 있고, 다음과 같이 개발자 도구의 Application 탭에서 확인할 수도 있다.

document.cookiename=value 쌍으로 구성되어있고, 각 쌍은 ; 로 구분한다.

쓰기

document.cookie 에 직접 값을 쓸 수 있다. document.cookie 에 값을 할당하면, 브라우저는 이 값을 받아 해당 쿠키를 갱신한다.

document.cookie="test=hi";

document.cookie 를 통해 방금 생성한 쿠키를 볼 수 있다.

Application 탭에서도 다음과 같이 쿠키가 생성된 것을 볼 수 있다.

document.cookie= 연산은 모든 쿠키를 덮어쓰는 것이 아닌 며잇된 쿠키의 값만 갱신한다. 쿠키의 이름과 값엔 모든 글자가 허용되지만 형식의 유효성을 일관성 있게 유지하기 위해 encodeURIComponent 를 사용하여 이름과 값을 이스케이프 처리해준다.

document.cookie = encodueURIComponent('name') + '=' + encodueURIComponent('value');

쿠키의 제약 사항

  • encodeURIComponent 로 인코딩한 이후의 name=value 쌍은 4KB를 넘을 수 없다.
  • 도메인 하나당 저장할 수 있는 쿠키의 개수는 20여 개로 한정되어 있으며, 브라우저마다 약간의 차이가 있다.

쿠키의 옵션

쿠키에는 몇가지 옵션이 있는데 몇몇 옵션은 꼭 지정해 줘야 할만큼 중요하다.

옵션은 key=value 뒤에 나열하고 ; 로 구분한다.

document.cookie = "test=hi; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT";

개발자 도구의 Application 탭에서도 확인할 수 있다.

path

  • path=/mypath

이 경로나 이 경로의 하위 경로에 있는 페이지만 쿠키에 접근할 수 있다. 절대 경로이어야 하고, 기본값은 현재 경로이다.

path=/practice 에서 설정한 쿠키는 /practice/practice/test 에선 볼 수 있지만, /playground 에선 볼 수 없다.

practice/index.html

practice/test.html

playground/index.html

특별한 경우가 아니라면, path 옵션을 path=/ 같이 루트로 설정해 웹사이트 모든 페이지에서 쿠키에 접근할 수 있도록 하는 것이 좋다.

domain

  • domain=site.com

쿠키에 접근 가능한 도메인을 지정한다. domain 옵션에 아무 값도 넣지 않았다면, 쿠키를 설정한 도메인에서만 쿠키에 접근할 수 있다. site.com 에서 설정한 쿠키는 other.com 에서 얻을 수 없다.

또한 서브 도메인이나 다른 도메인에서 쿠키에 접속할 방법은 없다. 이런 제약 사항은 안정성을 높이기 위해 만들어졌다.

하지만 서브 도메인에서 쿠키 정보를 얻는 방법이 완전히 없는 것은 아니다. 쿠키를 설정할 때 domain 옵션에 루트 도메인을 명시적으로 설정해 주면 된다.

document.cookie = "test=hi; domain=test.com";

//sub.test.com와 같은 서브도메인에서도 쿠키 정보를 얻을 수 있다.
console.log(document.cookie) // test=hi 를 확인 가능

구식 브라우저를 지원하려면 domain=.site.com 같이 . 을 앞에 붙인 표기법을 사용하는 것이 좋다.

서브 도메인이란 도메인 이름의 확장자 역할을 하여 웹사이트의 다양한 섹션을 구성 및 탐색할 수 있도록 지원한다. 또한 서브 도메인은 입력하고 기억하기 쉬운 것이어야 한다.

store.yoursite.com에서 store가 하위 도메인이고 yoursite가 주 도메인이며 .com은 최상위 도메인이다.

출처: https://kr.godaddy.com/help/what-is-a-subdomain-296

expires, max-age

expires나 max-age 옵션이 지정되어있지 않으면, 브라우저가 닫힐 때 쿠키도 함께 삭제된다. 이런 쿠키를 세션 쿠키라고 부른다.

expiresmax-age 옵션을 설정하면 브라우저를 닫아도 쿠키가 삭제되지 않는다.

  • expires=Sat, 23 Oct 2021 15:00:00 GMT

    브라우저는 설정된 유효 일자까지 쿠키를 유지하며, 해당 알지가 도달하면 쿠키를 자동 삭제한다.

쿠키의 유효 일자는 반드시 GMT 포맷으로 설정한다. date.toUTCString 을 통해 해당 포맷으로 쉽게 변경 가능하다.

document.cookie = `test=hi; expires=${date.toUTCString()}`;
  • max-age=3600

max-ageexpires 옵션의 대안으로, 쿠키 만료 기간을 설정할 수 있게 해준다. 현재부터 설정하고자 하는 만료일시까지의 시간을 초로 환산한 값을 설정한다.

// 1분 후 쿠키 삭제
document.cookie = "test=hi; max-age=60";

secure

  • secure

이 옵션을 설정하면 HTTPS로 통신하는 경우에만 쿠키가 전송된다.

document.cookie = "test=hi; secure";

samesite

samesite 옵션은 크로스 사이트 요청 위조(cross-site request forgery, XSRF) 공격을 막기 위해 만들어진 옵션이다.

samesite 의 옵션엔 두 가지 값(strict, lax)을 설정할 수 있다.

  • samesite=strict (default 값)

사용자가 사이트 외부에서 요청을 보낼 때, samesite=strict 옵션이 있는 쿠키는 절대로 전송되지 않는다. 예를 들어 메일에 있는 링크를 따라 접속하거나 다른 사이트에서 폼을 전송하는 경우 등과 같이 제 3자의 도메인에서 요청이 이뤄질 땐 쿠키가 전송되지 않는다.

  • samesite=lax

laxstrict 보다 느슨하면서도 XSRF 공격을 막을 수 있는 접근법이다. lax 도 사이트 외부에서 요청을 보낼 때 브라우저가 쿠키를 보내는 것을 막지만 예외가 있다.

다음 두 조건을 동시에 만족하면 쿠키가 전송된다.

  1. 안전한 HTTP 메서드인 경우(GET → O, POST → X)
  2. 작업이 최상위 레벨 탐색에서 이루어질 때(브라우저 주소창에서 URL 변경)
    • <iframe> 안에서 탐색이 일어나거나 AJAX 요청은 이 조건에 해당하지 못한다.

samesite 는 오래된 브라우저에선 지원하지 않는다는 문제점이 있다.

httpOnly

httpOnly 옵션은 웹서버에서 Set-Cookie 헤더를 이용해 쿠키를 설정할 때 지정할 수 있다.

이 옵션은 자바스크립트 같은 클라이언트 측 스크립트가 쿠키를 사용할 수 없게 한다. document.cookie 를 통해 쿠키를 볼 수도 없고 조작할 수 도 없다.

httpOnly 를 통해서 악의적으로 코드를 이용하여 쿠키에 접근하는 것을 방지할 수 있다.

Reference

쿠키와 document.cookie

HTTP 쿠키 - HTTP | MDN

profile
알고리즘과 프론트엔드 부셔버리기

0개의 댓글