8주 차 3부 식별, 인가, 보안 파트에 진입했습니다. 그리고 11장 클라이언트 식별과 쿠키가 처음 저를 맞이하더군요. 쿠키! 최근 사이드 프로젝트에서 쿠키를 생성해서 일주일간 보지 않기를 설정했었는데, 한번 봤다고 또 내심 반가웠어요. 아무튼 쿠키에 대해서 좀 더 알 수 있는 기회가 될 것이라 생각하고 재밌게 읽었습니다 :)
HTTP는 익명으로 사용하며, 상태가 없고 요청과 응답으로 통신하는 프로토콜이다.
현대의 웹 사이트들은 개인 사용자들에 대해 더 많은 것을 알고 싶어 하고, 기록하고 싶어한다. 그렇기에 맞춤형으로 사이트를 개인화 시켜서 사용자에게 제공한다!
사용자에게 정보를 전달하는 가장 일반적인 일곱 가지 HTTP 요청 헤더를 살펴보자!
헤더 이름 | 헤더 아팁 | 설명 |
---|---|---|
From | 요청 | 사용자의 이메일 주소 |
User-Agent | 요청 | 사용자의 브라우저 |
Referer | 요청 | 사용자가 현재 링크를 타고 온 근원 페이지 |
Authorization | 요청 | 사용자 이름과 비밀번호(뒤에서 다룸) |
Client-ip | 확장(요청) | 클라이언트의 IP 주소 |
X-Forward-Fpr | 확장(요청) | 클라이언트의 IP 주소 |
Cookie | 확장(요청) | 클라이언트의 IP 주소 |
사용자 식별에 클라이언트 IP주소를 사용할 수 있을까?
우리가 아는 그 로그인이 맞다.
하지만... 로그인은 매우 귀찮은 일이다! 사이트마다 로그인을 해야함은 물론이고, 사이트마다 이름과 비밀번호를 기억해야 한다는건 매우 매우 좋지 않다.
사용자의 URL마다 상태 정보를 포함하고 있는 URL을 의미한다. 이 또한 피해 갈 수 없는 단점이 존재한다.
쿠키는 사용자를 식별하고 세션을 유지하는 방식 중에서 현재까지 가장 널리 사용하는 방식이다.
세션쿠키는 사용자가 브라우저를 닫으면 삭제 된다. 또한 사용자가 사이트를 탐새할 때, 관련한 설정과 선호 사항들을 저장하는 임시 쿠키다.
지속 쿠키는 디스크에 저장되기 때문에 삭제되지 않고 더 길게 유지될 수 있다. 주기적으로 방문하는 사이트에 대한 설정 정보나 로그인 이름을 유지하려고 사용한다.
둘이 다른 점은 파괴되는 시점뿐이다.
서버가 사용자에게 "안녕! 나는..!" 라고 붙이는 스티커다. 사용자가 웹 사이트에 방문하면, 웹 사이트는 스티커를 읽을 수 있다.
쿠키는 임의의 이름=값
형태의 리스트를 가지고, 리스트는 Set-Cookie 혹은 Set-Cookie2(확장 헤더)같은 HTTP 응답 헤더에 기술되어 사용자에게 전달된다.
쿠키는 어떤 정보든 포함할 수 있다.
쿠키의 기본적인 발상은 브라우저가 서버 관련 정보를 저장하고, 사용자가 해당 서버에 접근할 때마다 그 정보를 함께 전송하는 것이다. 브라우저는 쿠키 정보를 저장할 책임이 있고, 이 시스템을 클라이언트 측 상태
라고 한다.
브라우저는 수백 수천개의 쿠키를 가지고 있을 수 있지만, 쿠키 전부를 모든 사이트에 보내지는 않는다. 보통은 쿠키를 생성한 서버에게만 쿠키에 담긴 정보를 전달한다.
서버는 쿠키를 생성할 때 Set-Cookie 응답 헤더에 Domain 속성을 기술해서 어떤 사이트가 그 쿠키를 읽을 수 있는지 제어할 수 있다. 다음과 같은 도메인을 가진다고 해보자.
Set-Cookie: "user=malza"; domain=".malzahttp.com"
;
사용자가 www.malzahttp.com
이나 what.malzahttp.com
처럼 .malzahttp.com으로 끝나는 사이트를 방문하면 해당 Cookie 헤더가 항상 적용 될 것이다.
웹 사이트 일부에만 쿠키를 적용하고 싶어!
Set-Cookie: pref=compact; path="/study/"
;
사용자가 http://www.malzahttp.com
에 접근하면
Cookie: user=malza
쿠키만 얻을 수 있다. 사용자가 http://www.malzahttp.com/study
에 접근하면
Cookie: user=malza
Cookie: pref=compact
와 같은 쿠키를 얻을 수 있다.
Set-Cookie 속성 | 설명 |
---|---|
이름=값 | 필수 속성으로 이름= 값의 형태를 가진다. 그 어떤 이름=값 조합이든 만들 수 있다. Set-Cookie: customer=Malza |
Expires | 선택 속성으로 쿠키의 생명주기를 나타내는 날짜 문자열을 기술한다. 일단 파기 일자에 다다르면 쿠키는 삭제된다. Set-Cookie: foo-bar; expires=Wednesday, 09:Nov:99 21:12:40 GMT |
Domain | 선택 속성으로 브라우저는 이 속성에 기술된 도메인을 사용하는 서버 호스트 명으로만 쿠키를 전송한다. Set-Cookie: SHIPPING=FEDEX; domain="joes-hardware.com" |
Path | 선택적인 속성으로 서버에 있는 특정 문서에만 쿠키를 할당할 수 있다. 만약 Path속성에 기술된 값이 URL 경로의 앞부분과 일치하면 쿠키를 전달한다. '/foo' 경로는 '/foobar' 와 /foo/bar.html'에 들어맞는다. |
Secure | 선택적인 속성으로 쿠키는 HTTP가 SSL 보안 연결을 사용할 때만 쿠키를 전송한다. |
version0 넷스케이프 표준보다 더 많은 속성이 있다. version0에 없는 속성만 기술해보자.
Set-Cookie2 속성 | 설명 |
---|---|
Version | 필수 속성으로 쿠키 명세의 버전을 가리키는 정수 값이다. Version="1" |
Comment | 선택 속성으로 서버가 쿠키를 사용하려는 의도를 기술한다. |
CommentURL | 선택 속성으로 쿠키를 사용하는 목적과 정책에 대해 상세히 기술된 웹페이지 URL링크를 제공한다. |
Discard | 선택적인 속성으로 클라이언트 프로그램이 종료될 때 클라이언트가 해당 쿠키를 삭제한다. |
Max-Age | 선택적인 속성으로 쿠키의 생명주기를 초 단위로 산정한 정수 값이다. 쿠키의 나이가 Max-Age보다 더 많아지면, 클라이언트는 쿠키를 제거해야 한다. |
Port | 선택적인 속성으로 값이 없이 속성의 키워드(Port)만 기술할 수도 있고, 쿠키가 적용될 포트 한 개 이상을 콤마로 구분하여 기술할 수 있다. Port="80,81,8000" Port |
만약 서버가 새로운 형식의 쿠키를 인식하면, Cookie2 헤더를 받고 나서 Set-Cookie2 응답 헤더를 보내야 한다.
만약 클라이언트가 같은 쿠키를 Set-Cookie와 Set-Cookie2 헤더에 기술해서 모두 보내면, 이전 방식인 Set-Cookie 헤더를 무시한다.
클라이언트가 Version 0 쿠키와 Version 1 쿠키를 모두 지원하더라도 서버로부터 Version 0의 Set-Cookie헤더를 받으면, 클라이언트는 Version 0 Cookie 헤더를 보내야만 한다.