11.1 개별 접촉

  • HTTP는 익명으로 사용하며 상태가 없고, 요청과 응답으로 통신하는 프로토콜이다.
  • 웹 서버는 요청을 보낸 사용자를 식별하거나 방문자가 보낸 연속적인 요청을 추적하기 위해 약간의 정보를 이용할 수 있다.
  • 네트워크로 연결된 사용자들에 대해 더 많은 것을 알고 싶어 하고 사용자들이 브라우징하는 것을 기록하고 싶어한다.

  • 개별인사
    • 개인에게 맞춰져 있는 것처럼 느끼게 하기 위해 사용자에게 특화된 환영 메시지나 페이지 내용을 만든다.
  • 사용자 맞춤 추천

  • 저장된 사용자 정보

  • 세션 추적
    • HTTP 트랜잭션은 상태가 없고(stateless) 요청, 응답이 독립적으로 일어난다.
    • 사용자가 사이트와 상호작용할 수 있게 사용자의 상태를 남긴다. 이렇게 상태를 유지하려면 HTTP 트랜잭션을 식별할 방법이 필요하다.
  • 논의할 사용자 식별 기술
    • 사용자 식별 관련 정보를 전달하는 HTTP 헤더들
    • 클라이언트 IP 주소 추적으로 알아낸 IP 주소로 사용자 식별
    • 사용자 로그인 인증을 통한 사용자 식별
    • URL에 식별자를 포함하는 기술인 뚱뚱한(fat) URL
    • 식별 정보를 지속해서 유지하는 강력하면서도 효율적인 기술인 쿠키

11.2 HTTP 헤더

  • 사용자 정보 전달 HTTP 요청 헤더

    헤더 이름 헤더 타입 설명
    From 요청 사용자의 이메일 주소
    User-Agent 요청 사용자의 브라우저
    Referer 요청 사용자의 현재 링크를 타고 온 근원 페이지
    Authorization 요청 사용자 이름과 비밀번호
    Client-ip 확장(요청) 클라이언트의 IP 주소
    X-Forwarded-For 확장(요청) 클라이언트의 IP 주소
    Cookie 확장(요청) 서버가 생성한 ID 라벨
    • From
      • 사용자의 이메일 주소 포함
      • 스팸메일 때문에 안보내는 브라우저 또한 많다.
    • User-Agent
      • 사용자의 브라우저 이름, 버전, 운영체제에 대한 정보까지 포함하여 서버에 알려준다.
        // 크롬 User-Agent
        Mozila/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36
        
    • Refer
      • 사용자가 현재 페이지로 유입하게 한 웹페이지의 URL을 가리킨다.
      • Refer 헤더만으로 사용자를 식별할 수는 없지만, 방문 이력을 통해 사용자 특성을 알 수 있다.

11.3 클라이언트 IP 주소

  • 초기에는 사용자 식별을 IP주소를 사용했다.
  • 사용자가 확실한 IP를 가지고 있고, 바뀌지 않고, 웹 서버 요청마다 클라이언트의 IP를 알 수 있다면 문제없다.
  • 약점
    • 클라이언트 IP주소는 사용자가 아닌 PC를 가리킨다.
    • ISP에서 동적으로 IP 주소를 할당하기 때문에 사용자를 IP주소로 식별할 수 없다.
    • 보안을 강화하고 부족한 주소들을 관리하려고 많은 사용자가 네트워크 주소변환(NAT) 방화벽을 통해 인터넷을 사용한다.
    • HTTP 프락시와 게이트웨이는 원 서버에 새로운 TCP를 연결한다.
  • 인프라넷과 같이 제한된 영역에서는 적절하게 사용할 수 있다.

11.4 사용자 로그인

  • 웹 사이트 로그인이 더 쉽도록 WWW-Authenticate와 Authorization 헤더를 사용해 웹 사이트에 사용자 이름을 전달하는 체계를 가지고 있다.
  • 동작
    • 브라우저는 www.joes-hardware.com 으로 요청
    • 서버에서 사용자의 식별정보를 알지 못하므로 401 Login Required HTTP 응담 코드와 WWW-Authenticate 헤더를 반환하여 로그인을 요청한다. 이는 브라우저에 로그인 대화 상자를 띄우게 한다.
    • 로그인하여 기본 요청을 다시 보내서 사용자 식별을 시도한다.
    • 서버는 사용자의 식별 정보를 안다.
    • 이후 요청에 대해서 브라우저는 서버로부터 사용자 식별 정보를 요청받으면, 서버에서 오는 요청에 대해 자동으로 로그인 정보를 포함한다.
      • 이는 사이트에 한 번 로그인하면, 브라우저는 요청마다 해당 사용자의 식별정보 토큰을 Authentication 헤더에 담아 서버로 전송
      • 한 세션이 진행되는 내내 그 사용자에 대한 식별 유지

11.5 뚱뚱한 URL

  • 사용자의 상태 정보를 포함하고 있는 URL을 뚱뚱한 URL이라고 한다.
    <a href="/exec/obidos/tg/browse/-/229220/ref=gr_gifts/002-1145265-8016838">All Gifts</a>
    
    • 사용자에게 할당된 식별번호를 URL에 붙여서 사용자를 추적한다
  • 웹 서버와 통신하는 독립적인 HTTP 트랜잭션을 하나의 세션 혹은 방문으로 묶는 용도로 뚱뚱한 URL을 사용할 수 있다.
  • 문제
    • 못생긴 URL
      • 브라우저에 보이는 뚱뚱한 URL은 새로운 사용자들에게 혼란을 준다.
    • 공유하지 못하는 URL
      • 특정 사용자와 세션에 대한 상태 정보를 포함하므로 개인 정보를 공유하게 된다.
    • 캐시를 사용할 수 없음
      • URL로 만드는 것은 URL이 달라지기 때문에 기존 캐시에 접근할 수 없다는 것을 의미
    • 서버 부하 가중
      • 뚱뚱한 URL에 해당하는 HTML 페이지를 다시 그려야 한다.
    • 이탈
      • 뚱뚱한 URL 세션에서 이탈하기 쉽다.
    • 세션간 지속성의 부재

11.6 쿠키

  • 쿠키는 사용자를 식별하고 세션을 유지하는 방식 중에서 현재까지 가장 널리 사용하는 방식이다.
  • 쿠키는 앞서 설명한 기술들이 가지고 있던 문제점들은 없지만, 쿠키만으로 하기 힘든 일에는 앞서 설명한 기술들을 함께 사용하기도 한다.
  • 쿠키는 캐시와 충돌할 수 있어서, 대부분의 캐시나 브라우저는 쿠키에 있는 내용물을 캐싱하지 않는다.

  • 쿠키의 타입
    • 쿠키는 크게 세션 쿠키(session cookie)와 지속 쿠키(persistent cookie) 두 가지 타입으로 나눌 수 있다.
    • 세션 쿠키
      • 사용자가 사이트를 탐색할 때, 관련한 설정과 선호 사항들을 저장하는 임시 쿠키(브라우저를 닫으면 삭제)다.
    • 지속 쿠키
      • 디스크에 저장되어, 브라우저를 닫거나 컴퓨터를 재시작해도 남아있다.
      • 사용자가 주기적으로 방문하는 사이트에 대한 설정 정보나 로그인 이름을 유지하려고 사용한다.
    • 쿠키는 Discard 파라미터가 설정되어 있거나, 파기되기까지 남은 시간을 가리키는 Expires 혹은 Max-Age 파라미터가 없으면 세션 쿠키가 된다.
  • 쿠키는 어떻게 동작하는가
    • 처음에 사용자가 웹 사이트에 방문하면 웹 서버는 사용자에 대해 아무것도 모른다.
    • 웹 서버는 사용자가 다시 돌아왔을 때, 해당 사용자를 식별하기 위한 유일한 값을 쿠키에 할당한다.
    • 쿠키는 ‘임의의 이름=값’ 형태의 리스트를 가지고, 그 리스트는 Set-Cookie 혹은 Set-Cookie2(확장 헤더) 같은 HTTP 응답 헤더에 기술되어 전달한다.
    • 쿠키는 어떤 정보든 포함할 수 있지만, 서버가 사용자 추적 용도로 생성한 유일한 단순 식별 번호만 포함하기도 한다.
    • 예제
      • 서버는 id=”34294”라는 쿠키를 사용자에게 할당하는데, 서버는 이 쿠키 값으로 데이터베이스에서 사용자의 정보(구매 내용, 주소 정보 등)를 찾는데 사용할 수 있다.
      • 많은 웹 서버가 정보를 쿠키에 유지하려고 한다.
        eg. Cookie: name="Brian Totty" phone="555-1212"
        
    • 브라우저는 서버에서 온 Set-Cookie 헤더에 있는 쿠키 콘텐츠를 브라우저 쿠키 데이터베이스에 저장한다
    • 사용자가 미래에 같은 사이트를 방문하면, 브라우저는 서버가 이 사용자에게 할당했던 쿠키를 Cookie 요청 헤더에 기술해 전송한다.
  • 쿠키상자: 클라이언트 측 상태
    • 브라우저가 서버 관련 정보를 저장하고 그 서버에 접속할 때 마다 그 정보를 함께 보내는 것이다.
    • 브라우저는 쿠키 정보를 저장할 책임이 있는데, 이 시스템을 ‘클라이언트 측 상태’라고 한다.
    • 구글 크롬 쿠키
      • 각 브라우저는 각기 다른 방식으로 쿠키를 저장한다.
      • 구글 크롬은 Cookies라는 SQLite 파일에 쿠키를 저장한다.
      • 각 행이 쿠키 한 개에 해당하며, 총 13개 필드가 있는데 몇몇 주요 필드의 의미는 다음과 같다.
      • 필드 설명
        • creation_utc: 쿠키가 생성된 시점
        • host_key: 쿠키의 도메인
        • name: 쿠카의 이름
        • value: 쿠키의 값
        • path: 쿠키와 관련된 도메인에 있는 경로
        • expire_utc: 쿠키의 파기 시점
        • secure: 이 쿠키를 SSL 커넥션일 경우에만 보낼지를 가리킨다
    • 마이크로소프트 인터넷 익스플로러 쿠키
      • 익스플로러는 캐시 디 렉터리에 각각의 개별 파일로 쿠키를 저장한다.
  • 사이트마다 각기 다른 쿠키들
    • 브라우저는 수천 개의 쿠키를 가지고 있을 수 있지만, 각 사이트에 두 개 혹은 세 개의 쿠키를 보낸다. 이유는 다음과 같다.
    • 쿠키를 모두 전달하면 브라우저는 실제 콘텐츠의 바이트 보다 더 많은 쿠키 바이트를 보내게 될 것이므로 성능이 크게 저하된다.
    • 쿠키들의 대부분은 서버에 특화된 이름/값 쌍을 포함하고 있기 때문에, 대부분 사이트에서는 인식하지 않는 무의미한 값이다.
    • 모든 사이트에 쿠키 전체를 전달하는 것은, 특정 사이트에서 제공한 쿠키를 신뢰하지 않는 사이트에서 가져갈 수 있어 보안 문제를 일으킬 것이다.

    • 쿠키 Domain 속성
      • 서버는 쿠키를 생성한 때 Set-Cookie 응답 헤더에 도메인을 기술하여 어떤 사이트가 그 쿠키를 읽을 수 있는지 제어할 수 있다.
      • 예를 들어 다음 HTTP 응답 헤더는 브라우저가 user=”mary17”이라는 쿠키를 .airtravelbargains.com 도메인을 가지고 있는 모든 사이트에 전달한다는 의미다.
      • user=”mary17”; domain=”airtravelbargains.com”
      • 만약 사용자가 www.airtravelbargains.com나 specials.airtravelbargains.com과 같이 .airtravelbargains.com로 끝나는 사이트를 방문하면 다음 Cookie 헤더가 항상 적용될 것이다.
      • Cookie: user=”mary17”
    • 쿠키 Path 속성
      • URL 경로의 앞부분을 가리키는 Path 속성을 기술해서 해당 경로에 속하는 페이지만 쿠키를 전달한다.
      • www.airtravelbargains.com 사이트의 자동차를 대여하는 페이지인 www.airtravelbargains.com/authos/에서 사용자가 좋아하는 쿠키를 사용하려고 할 때 쿠키를 다음과 같이 생성한다.
      • Set-Cookie: pref=compact; domain=”airtravelbargains.com”; path=”/authos/”
      • 사용자가 www.airtravelbargains.com/specials.html에 접근하면 다음과 같은 쿠키만 얻게 된다.
      • Cookie: user=”mary17”
      • 하지만 사용자가 www.airtravelbargains.com/authos/cheapo/index.html로 접근하면 다음과 같은 쿠키를 얻게 된다.
      • Cookie: user=”mary17”
      • Cookie: pref=compact
      • 따라서 쿠키는 일종의 상태 정보라고 할 수 있으며, 서버가 생성하여 클라이언트에 전달하고, 클라이언트는 그 쿠키를 유효한 사이트에만 다시 전달하고 관리한다.
  • 쿠키 구성요소
    • 현재 사용되는 쿠키 명세에는 Version 0 쿠키(흔히 ‘넷스케이프 쿠키’라고 불린다)와 Version 1 쿠키(현재는 사용하지 않음)가 있다.
  • Version 0(넷스케이프) 쿠키
    • 최초의 쿠키 명세는 넷스케이프가 정의했다.
    • Version 0 쿠키는 Set-Cookie 응답 헤더와 Cookie 요청 헤데와 쿠키를 조작하는데 필요한 필드들을 정의하였다.

    • Version 0 쿠키의 형태
      • Set-Cookie: name=value [; expires=date][; path=path] [; domain=domain][; secure]
      • Cookie: name1=value1 [; name2=value2] …
      • Version 0 Set-Cookie 헤더
        • Set-Cookie 헤더는 쿠키의 이름과 값을 가져야 한다.
        • 쿠키 옵션 속성들에 세미콜론으로 이어 기술한다.
    • Version 0 Cookie 헤더
      • 클라이언트가 서버에 요청을 보낼 때는, Domain, Path, Secure 필터들이 현재 요청 하려고 하는 사이트에 들어맞으면서 아직 파기되지 않은 쿠키들을 함께 보낸다.
      • 모든 쿠키는 Cookie 헤더 안에 한데 이어 붙여 보낸다.
      • Cookie: session-id=002-1145265-8016832; session-id-time=1007883800
  • 쿠키와 세션 추적
    • 쿠키는 웹 사이트에 수차례 트랜잭션을 만들어내는 사용자를 추적하는데 사용한다.
    • 전자상거래 웹 사이트는 사용자가 온라인 쇼핑을 하는 중에도 그들의 쇼핑카트를 유지하려 세션 쿠키를 사용한다.
    • amazon.com에 접속하면 일어나는 트랜잭션들의 연속
    • 동작
      • 브라우저가 amazon.com의 루트 페이지를 처음 요청한다.
      • 서버는 클라이언트를 전자상거래 소프트웨어 URL로 리다이렉트 시킨다.
      • 클라이언트는 리다이렉트 URL로 요청을 보낸다.
      • 서버는 응답에 두 개의 세션 쿠키를 기술하고 사용자를 다른 URL로 리다이렉트 시킨다.
      • 클라이언트는 새로운 URL을 요청을 앞서 받은 두 개의 쿠키와 함께 보낸다.
      • 서버는 home.html 페이지로 리다이렉트 시키고 쿠키 두 개를 더 첨부한다.
      • 클라이언트는 home.html 페이지를 가져오고 총 네 개의 쿠키를 전달한다.
      • 서버는 콘텐츠를 보낸다.
  • 쿠키와 캐싱
    • 쿠키 트랜잭션과 관련된 문서를 캐싱하는 것은 주의해야 한다.
    • 캐시되지 말아야 할 문서가 있다면 표시하라
      • 만약 문서가 Set-Cookie 헤더를 제외하고 캐시를 해도 될 경우라면 그 문서에 명시적으로 Cache-Control: no-cache=”Set-Cookie”를 기술해서 명확히 표시한다.
      • 캐시를 해도 되는 문서에 Cache-Control: public을 사용하면 웹의 대역폭을 더 절약시켜준다.
    • Set-Cookie 헤더를 캐시 하는 것에 유의하라
      • 응답에 Set-Cookie 헤더를 가지고 있으면, 본문은 캐시할 수 있지만 Set-Cookie 헤더를 캐시하는 것은 주의가 필요하다.
      • 같은 Set-Cookie 헤더를 여러 사용자에게 보내면, 사용자 추적에 실패할 것이기 때문이다.
      • 일부 캐시는 응답을 저장하기 전에 Set-Cookie를 제거하기 때문에, 그 캐시 데이터를 받은 클라이언트는 문제가 발생할 수 있다.
      • 캐시가 모든 요청마다 원 서버와 재검사시켜 클라이언트로 가는 응답에 Set-Cookie 헤더 값을 기술해서 이 문제를 개선할 수 있다.
      • Cache-Control: must-revalidate, max-age=0
    • Cookie 헤더를 가지고 있는 요청을 주의하라
      • 요청이 Cookie 헤더와 함께 오면, 결과 콘텐츠가 개인정보를 담고 있을 수도 있다는 뜻이다.
      • 개인정보는 캐시되지 않도록 표시되어 있어야 하지만, 그 표시를 하지 않는 서버도 있다.

** 참고 서적: HTTP 완벽 가이드