11장 클라이언트 식별과 쿠키
개별 접촉
HTTP는 무상태(stateless) 프로토콜이다. 요청과 응답으로 통신하는 프로토콜이다.
웹 서버는 요청을 보낸 사용자를 식별하거나 방문자가 보낸 연속적인 요청을 추척하기 위해 약간의 정보를 이용할 수 있다.
아마존과 같은 사이트는 여러 방식으로 사이트를 개인화 시켜 사용자에게 제공한다.
개별인사
- 개인에게 맞춰져 있는 것처럼 느끼게 하기 위해 사용자 특화 메시지나 개인화된 페이지 내용을 만든다.
사용자 맞춤 추천
- 고객이 좋아할 것이라고 예상되는 제품들을 추천한다.
저장된 사용자 정보
- 사용자가 사이트에 로그인하면 사용자의 이름, 주소, 이메일 주소, 신용카드 번호 등의 정보를 저장한다.
세션추적
- HTTP 트랜잭션은 stateless 이기 때문에 사용자가 사이트를 방문할 때마다 새로운 연결이 만들어진다.
이전에 사용자가 사이트를 방문했던 기록을 추적하기 위해 세션 추적이라는 기술을 사용한다.- 사용자 식별 관련 정보를 전달하는 HTTP 헤더들
- 클라이언트 IP 주소 추적으로 알아낸 IP 주소로 사용자를 식별
- 사용자 로그인 인증을 통한 사용자 식별
- URL에 식별자를 포함하는 기술인 뚱뚱한 URL
- 식별 정보를 지속해서 유지하는 강력하고 효율적인 쿠키
HTTP 헤더
헤더 이름 | 헤더 타입 | 설명 |
---|---|---|
From | 요청 | 사용자의 이메일 주소 |
User-Agent | 요청 | 사용자의 브라우저 |
Referer | 요청 | 사용자가 이전에 방문했던 사이트의 근원 페이지 |
Authorization | 요청 | 사용자의 인증 정보 |
Client-IP | 확장(요청) | 사용자의 IP 주소 |
X-Forwarded-For | 확장(요청) | 사용자의 IP 주소 |
Cookie | 확장(요청) | 서버가 생성한 ID라벨 |
클라이언트 IP주소
초기의 웹 선구자들은 사용자 식별에 사용자의 IP 주소를 사용했다.
하지만 IP 주소는 사용자를 식별하기에 적합하지 않다.
- 클라이언트 IP 주소는 사용자가 아닌 사용하는 컴퓨터를 의미한다.
- 많은 인터넷 서비스 제공자(ISP)는 사용자가 로그인하면 동적으로 IP 주소를 할당한다.
- 보안을 강화하고 부족한 주소들을 관리하려고 많은 사용자가 네트워크 주소 변화(NAT) 방화벽을 통해 인터넷을 사용한다. NAT장비들은 클라이언트의 실제 IP주소를 방화벽 뒤로 숨기고, 클라이언트의 실제 IP주소를 내부에서 사용하는 하나의 방화벽 IP주소로 변환한다.
- 보통 HTTP 프락시와 게이트웨이는 원 서버에 새로운 TCP 연결을 한다. 여전히 세션 간의 사용자 식별을 위해 IP 주소를 사용하는 경우가 있다. 하지만 제대로 동작하지 않거나 IP 주소를 임의로 변경할 수 있기에 사용되지 않는다.
사용자 로그인
- IP 주소로 사용자를 식별하려는 수동적인 방식보다, 웹 서버는 사용자 이름과 비밀번호로 인증할 것을 요구해서 사용자에게 명시적으로 식별 요청을 할 수 있다.
- 웹 사이트 로그인이 더 쉽도록 HTTP는 WWW-Authenticate와 Authorization 헤더를 사용해 웹 사이트에 사용자 이름을 전달하는 자체적인 체계를 제공한다.
- 서버에서 사용자가 사이트에 접근하기 전에 로그인을 시키고자 한다면 HTTP 401 Login Required 응답 코드를 브라우저에 보낼 수 있다.
뚱뚱한 URL
- 어떤 웹 사이트는 사용자의 URL마다 버전을 기술하여 사용자를 식별하고 추적한다.
- 사용자의 상태 정보를 포함하고 있는 URL을 뚱뚱한 URL이라고 한다.
- 웹 서버와 통신하는 독립적인 HTTP 트랜잭션을 하나의 세션 혹은 방문으로 묶는 용도로 뚱뚱한 URL을 사용할 수 있다.
- 뚱뚱한 URL은 사이트를 브라우징하는 사용자를 식별하는데 사용할 수 있다.
뚱뚱한 URL은 사용자를 식별하는데 사용할 수 있지만, 심각한 문제들이 존재한다.
- 못생긴 URL : 브라우저에 보이는 뚱뚱한 URL은 새로운 사용자들에게 혼란을 준다
- 공유하지 못하는 URL : 뚱뚱한 URL은 특정 사용자와 세션에 대한 상태 정보를 포함하며 공유한다.
- 캐시를 사용할 수 없음: URL로 만드는 것은, URL이 달라지기 때문에 기존 캐시에 접근할 수 없다는 것을 의미한다.
- 서버 부하 가중 : 서버는 뚱뚱한 URL에 해당하는 HTML 페이지를 다시 그려야 한다.
- 이탈 : 사용자가 링크를 타고 다른 사이트로 이동하는 경우, 뚱뚱한 URL 세션에서 이탈하기가 쉽다.
- 세션 간 지속간의 부재 : 사용자가 특정 뚱뚱한 URL을 북마킹하지 않는 이상, 로그아웃시 모든 정보를 잃는다.
쿠키
사용자를 식별하고 세션을 유지하는 방식 중에서 현재까지 가장 널리 사용하는 방식.
앞선 기술들이 가진 문제들을 겪지는 않지만 쿠키와 앞선 기술들을 혼합해서 사용하기도 한다.
쿠키는 캐시와 충돌할 수 있으므로 대부분의 캐시나 브라우저는 쿠키에 있는 내용물을 캐싱하지 않는다.
쿠키의 타입
크게 세션 쿠키(session cookie)와 지속 쿠키(persistent cookie) 두 가지 타입으로 나눌 수 있다.
- 세션 쿠키는 사용자가 사이트를 탐색할 때, 관련한 설정과 선호 사항들을 저장하는 임시 쿠키다.
- 세션 쿠키는 사용자가 브라우저를 닫으면 삭제된다.
- 지속 쿠키는 삭제되지 않고 더 길게 유지될 수 있다.
- 지속 쿠키는 디스크에 저장되어 브라우저를 닫거나 컴퓨터를 재시작하더라도 남아있다.
- 지속 쿠키는 사용자가 주기적으로 방문하는 사이트에 대한 설정 정보나 로그인 이름을 유지하려고 사용한다.
- 세션 쿠키와 지속 쿠키의 다른 점은 파기되는 시점 뿐이다.
- 쿠키는 Discard 파라미터가 설정 되어 있거나, Expires 혹은 Max-Age 파라미터가 없으면 세션 쿠키가 된다.
쿠키는 어떻게 동작하는가
- 쿠키는 임의의 이름=값 형태의 리스트를 가지고 리스트는 Set-Cookie, Set-Cookie2 같은 HTTP 응답 헤더에 기술되어 사용자에게 전달한다.
- 쿠키는 어떤 정보든 포함할 수 있지만 서버가 사용자 추적 용도로 생성한 유일한 단순 식별 번호만 포함하기도 한다.
쿠키 상자: 클라이언트 측 상태
- 쿠키의 기본적인 발상은 브라우저가 서버 관련 정보를 저장하고, 사용자가 해당 서버에 접근할 때마다 그 정보를 함께 전송하게 하는 것이다.
- 브라우저는 쿠키 정보를 저장할 책임이 있는데, 이 시스템을 클라이언트 측 상태라고 한다. 쿠키 명세에서의 공식적인 이름은 ‘HTTP 상태 관리 체계’이다.
구글 크롬 쿠키
- creation_utc : 쿠키가 생성된 시점
- host_key : 쿠키의 도메인
- name : 쿠키의 이름
- value : 쿠키의 값
- path : 쿠키와 관련된 도메인에 있는 경로
- expire_utc : 쿠키의 파기 시점, 파기될 시점을 초단위로 기술
-
secure : 쿠키를 SSL 커넥션일 경우에만 보낼지를 가리킨다.
마이크로소프트 인터넷 익스플로러 쿠키
- 캐시 디렉터리에 각각의 개별 파일로 쿠키를 저장한다.
- 파일에 있는 각 쿠키의 첫번째 줄은 쿠키이름이고 다음 줄은 쿠키의 값이다.
- 세 번째 줄에는 도메인과 경로가 있다.
사이트마다 각기 다른 쿠키들
브라우저는 수백 수천 개의 쿠키를 가지고 있을 수 있지만 쿠키 전부를 모든 사이트에 보내지 않는다. 일반적으로는 두 개 혹은 세 개의 쿠키만을 보낸다.
그 이유는
- 쿠키를 모두 전달하면 성능이 크게 저하된다.
- 쿠키들 대부분은 서버에 특화된 이름/값 쌍을 포함하고 있기 때문에 대부분 사이트에서는 인식하지 않는 무의미한 값이다.
- 모든 사이트에 쿠키 전체를 전달하는 것은 특정 사이트에서 제공한 정보를 신뢰하지 않는 사이트에서 가져갈 수도 있다. 보통 브라우저는 쿠키를 생성한 서버에게만 쿠키에 담긴 정보를 전달한다.
쿠키의 Domain 속성
서버는 쿠키를 생성할 때 Set-Cookie 응답 헤더에 Domain 속성을 기술해서 어떤 사이트가 그 쿠키를 읽을 수 있는지 제어할 수 있다.
Set-Cookie: name=value; domain=.example.org
쿠키의 Path 속성
서버는 쿠키를 생성할 때 Set-Cookie 응답 헤더에 Path 속성을 기술해서 어떤 경로에서 쿠키를 읽을 수 있는지 제어할 수 있다.
Set-Cookie: name=value; path=/blog
쿠키 구성요소
현재 사용되는 쿠키 명세에는 Version 0 쿠키(넷스케이프 쿠키)와 Version 1 쿠키(RFC 2965)가 있다.
Version 1 쿠키는 Version 0 쿠키의 확장으로 널리 쓰이지는 않는다.
Version 0(넷스케이프) 쿠키
형태는 다음과 같다.
Set-Cookie: name=value [; expires=date] [; path=path] [; domain=domain] [; secure]
Cookie: name1=value1 [; name2=value2] ...
Version 0 Set-Cookie 헤더
Set-Cookie 헤더 | 설명과 용례 |
---|---|
name=value | 쿠키의 이름과 값 |
expires=date | 쿠키의 파기 시점 |
path=path | 쿠키와 관련된 도메인에 있는 경로 |
domain=domain | 쿠키를 읽을 수 있는 도메인 |
secure | 쿠키를 SSL 커넥션일 경우에만 보낼지를 가리킨다. |
Version 0 Cookie 헤더
쿠키는 Cookie 헤더에 한데 이어 붙여 보낸다.
Cookie: sessionid=1234; session-id-time=1007884800
Version 1 (RFC 2965) 쿠키
넷크케이프 표준보다 좀 더 복잡하며 아직 모든 브라우저나 서버에서 지원하지 않는다.
추가적인 변경 사항들
- 쿠키마다 그 목적을 설명하는 설명문이 있다.
- 파기 주기에 상관없이 브라우저가 닫히면 쿠키를 강제로 삭제할 수 있다.
- 절대 날짜 값 대신에 초 단위의 상대 값으로 쿠키의 생명주기를 결정할 수 있는 Max-Age
- 단순히 도메인과 경로뿐 아니라 URL의 포트번호로도 쿠키를 제어할 수 있다.
- 도메인, 포트, 경로 필터가 있으면 Cookie 헤더에 담겨 되돌려 보낸다.
- 호환되는 버전번호.
- 사용자 이름과 추가적인 키워드를 구별하기 위해 Cookie 헤더에 $ 접두어가 있다.
Version 1 Set-Cookie2 헤더
Set-Cookie2 속성 | 설명과 용례 |
---|---|
name=value | 쿠키의 이름과 값 |
Version=1 | 쿠키의 버전 번호 |
Comment=comment | 쿠키의 설명 |
CommentURL=URL | 쿠키의 설명 URL |
Discard | 브라우저가 닫히면 쿠키를 삭제 |
Domain=domain | 쿠키를 읽을 수 있는 도메인 |
Max-Age=secs | 쿠키의 파기 시점 |
Path=path | 쿠키와 관련된 도메인에 있는 경로 |
Port=”port-list” | 쿠키를 읽을 수 있는 포트 |
Secure | 쿠키를 SSL 커넥션일 경우에만 보낼지를 가리킨다. |
쿠키와 세션 추적
쿠키는 웹 사이트에 수차례 트랜잭션을 만들어내는 사용자를 추적하는데 사용
쿠키와 캐싱
쿠키 트랜잭션과 관련된 문서를 캐싱하는 것은 주의해야 한다.
이전 사용자의 쿠키가 캐시된 문서를 다른 사용자에게 전달할 수 있기 때문이다.
캐시가 되지 말아야 할 문서가 있으면 표시하라
- 문서를 캐시하면 될지 안될지는 문서의 소유자가 제일 안다.
- 이 경우, Cache-Control: no-cache=”Set-Cookie” 을 기술해서 명확히 표시한다.
Set-Cookie 헤더를 캐시 하는 것에 유의하라
- 만약 응답이 Set-Cookie 헤더를 가지고 있으면, 본문은 캐싷라 수 있지만 Set-Cookie 헤더를 캐시하는 것은 주의를 기울여야만 한다.
- 어떤 캐시는 응답을 저장하기 전에 Set-Cookie 헤더를 제거하기 때문에, 그 캐시 데이터를 받는 사용자는 쿠키를 받지 못한다.
- 캐시가 모든 요청마다 원 서버와 재검사시켜 클라이언트로 가는 응답에 Set-Cookie 헤더 값을 기술해서 이 문제를 개선할 수 있다.
Cookie 헤더를 가지고 있는 요청을 주의하라
- 요청이 Cookie 헤더와 함께 오면, 결과 콘텐츠가 개인저보를 담고 있을 수도 있다.
- 경우에 따라 Cookie를 캐싱하거나 혹은 캐싱하지 않는 경우도 많다.
쿠키, 보안 그리고 개인정보
- 쿠키를 사용하지 않도록 비활성화시킬 수도 있고, 로그 분석과 같은 다른 방법으로 대체가능하므로 그 자체가 보안상으로 엄청나게 위험한 것은 아니다.
- 개인정보를 다루거나 사용자를 추적하는 기술은 잘못된 의도로 사용될 수 있기 때문에 항상 조심하는 것이 좋다.
- 사이트의 개인정보 정책에만 유의한다면, 쿠키에 관련한 위험성보다 세션 조작이나 트랜잭션 상의 편리함이 더 크다.