
HTTP에서 서버가 클라이언트의 상태를 보존하지 않는 것을 무상태 프로토콜이라고 합니다. 이 방식으로 인해 이전에 통신을 했던 클라이언트에 대해서 다음 통신에서 이전에 전달한 데이터를 유지하지 않게 됩니다.
무상태성으로 인해서 이전 요청에 대한 정보가 필요할 때 어떤 처리를 하기 어려운 경우가 생깁니다. 예를 들면, 로그인 된 유저를 상태로 저장하고 있고, 이에 따라 다른 페이지로 넘어가는 것과 같이 로그인 된 유저 정보가 필요한 요청에 대해서 매번 로그인을 다시해야 하는 문제가 생길 수 있습니다.
이런 문제는 어떻게 해결해야 할까요?
쿠키는 서버가 사용자의 웹 브라우저에 보내는 작은 데이터입니다. 브라우저에서는 쿠키를 저장하고 이후에 그 쿠키는 같은 서버에 의해 만들어진 요청들의 cookie HTTP 헤더 안에 포함되어 전송됩니다. 보통 쿠키는 다음과 같은 목적으로 사용됩니다.
- 로그인, 쇼핑 카트, 게임 점수 등 서버가 기억해야 하는 것
- 사용자 기본 설정, 테마 및 기타 설정
- 사용자 행동 기록 및 분석
쿠키는 과거 클라이언트측의 저장소로 사용되었지만, 크기가 크지 않았고 이제는 스토리지 API가 제공되기 때문에 그런 용도로 사용되지 않습니다. 클라이언트에서 한 사이트에 저장 가능한 쿠키는 최대 20개이고, 용량은 최대 4KB이지만, 웹 스토리지에는 5MB까지 저장이 가능하기 때문이죠.
요청을 할 도메인에 대해 쿠키가 존재한다면, 웹 브라우저는 도메인에게 요청할 때 쿠키를 담아서 함께 전달합니다.
HTTP 응답 해더에서 쿠키를 전달할 때 아래와 같이 전달합니다.
Set-Cookie: <cookie-name>=<cookie-value>
예시는 아래와 같습니다.
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[page content]
서버는 응답 시 위와 같은 방식으로 쿠키를 브라우저에게 전달합니다.
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
그 후 브라우저는 위와 같이 저장된 쿠키를 해더에 담아 요청을 보내게 됩니다.
도메인은 서버에 접속할 수 있는 이름입니다. 서버에서 도메인을 특정하지 않았다면, 브라우저는 기본적으로 같은 host에만 쿠키를 전달할 것입니다. 이때 서브 도메인은 제외됩니다.
MDN에는 아래와 같은 예시가 있습니다.
만약 Domain=mozilla.org이 설정되면, 쿠키들은 developer.mozilla.org와 같은 서브도메인 상에 포함되게 됩니다.
Path는 서버가 라우팅할 때 사용하는 경로로, 해당 경로와 다른 경로로 요청하게 된다면 쿠키를 서버에 전송할 수 없습니다. 하지만, 해당 경로의 하위 경로로 요청을 할 때는 쿠키 전송이 가능합니다. 즉, URL 내에 반드시 존재해야 하는 경로가 되는 것입니다.
예를 들면, /users로 Path가 설정되어 있을 때, /users/:id와 같이 하위 경로가 있는 서버 요청에서는 쿠키 전송이 가능하지만, /posts/:id와 같이 다른 경로의 경우는 쿠키 전송이 불가능합니다.
쿠키의 유효기간을 설정할 수 있습니다. 만약, 쿠키의 유효기간이 설정되어 있지 않다면, 쿠키는 세션 쿠키가 됩니다. 클라이언트가 종료되면 세션이 종료되고, 그 후에 세션 쿠키가 제거가 됩니다. 즉, 브라우저를 종료하면 쿠키가 삭제됩니다.
MaxAge는 쿠키의 유효기간을 초 단위로 설정해줍니다.
Expires는 쿠키가 언제까지 유요한지 날짜를 정할 수 있습니다. 이때 옵션의 값은 클라이언트의 시간을 기준으로 합니다.
이렇게 유효기간을 정해준 쿠키를 영속성 쿠키라고 합니다. 예시는 아래와 같습니다.
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Secure을 true로 설정한 경우, https:스키마로 요청이 있을 때만 쿠키가 서버로 전송되게 됩니다. 하지만 Secure 쿠키라고해도 민감한 정보를 쿠키에 저장해서 전송하면 안됩니다. Secure이라고 해도 실질적인 보안을 제공하지 않기 때문이죠. 즉, 쿠키 자체가 암호화되지 않는다는 것입니다.
자바스크립트로 브라우저의 쿠키에 접근이 가능한지 여부를 결정합니다. 자바스크립트로 쿠키에 접근이 가능하다면 document.cookie를 이용해서 쿠키를 탈취할 위험이 있습니다. Cross-site 스크립팅 공격을 방지하기 위해서 HttpOnly쿠키를 사용하게 되면 자바스크립트로 쿠키에 접근이 불가능 하게 됩니다.
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
SameSite 쿠키는 cross-origin요청을 받은 경우, 요청한 방식(메소드)와 옵션을 기준으로 서버의 쿠키 전송 여부를 결정합니다. 그렇기 때문에 CSRF(cross-site 요청 위조 공격)에 대한 보호 방법을 제공하게 됩니다. 하지만, 아직 실험 중에 있기 때문에 아직 제공되지 않는 브라우저가 있을 수 있습니다.
SameSite쿠키의 옵션은 아래와 같습니다.
- Lax : Cross-Origin 요청일 때,
GET메소드만 쿠키를 전송할 수 있습니다.- Strict : 가장 엄격한 옵션으로, Cross-Origin이 아닌 Same Site인 경우에만 쿠키를 전송합니다.
- None : Cross-Origin에 상관없이 항상 쿠키를 보내줄 수 있습니다. 단,
Secure옵션이 필요합니다.