# 클라이언트 식별과 쿠키
이 장에서는 서버가 통신하는 대상을 식별하는데에 사용하는 기술을 알아본다.
## 개별 접촉
HTTP는 익명으로 사용하며 상태가 없고 요청(Request)과 응답(Response)로 통신하는 프로토콜
현대의 웹 사이트들은 개인화된 서비스들을 제공하고 싶어한다.
### 개별 인사
개인에게 맞춰져 있는 것처럼 느끼게 하려고 사용자에게 특화된 환영 메세지나 페이지 내용을 만듦
### 사용자 맞춤 추천
고객의 흥미가 무엇인지 학습해서 고객이 좋아할 만한 상품을 추천해준다.
개개인의 기념일이나 생일이 다가오면 그에 맞는 상품을 제시할 수도 있다.
### 저장된 사용자 정보
배송지 주소와 카드 정보를 매번 입력받게 하지말고
데이터베이스에 저장하여 저장하는 경우를 말한다.
### 세션 추적
HTTP 트랜잭션은 상태가 없다.
각 요청, 응답은 독립적으로 일어난다.
사용자가 사이트와 상호작용 할 수 있게 사용자의 상태를 남기는데,
여러 상태들을 유지하려면, 웹 사이트는 HTTP 트랜잭션을 식별할 방법이 필요하다.
- 사용자 식별 관련 정보를 전달하는 HTTP 헤더들
- 클라이언트 IP 주소 추적으로 알아낸 IP 주소로 사용자 식별
- 사용자 로그인 인증을 통한 사용자 식별
- URL에 식별자를 포함하는 뚱뚱한 URL
- 식별 정보를 지속해서 유지하는 쿠키
## HTTP 헤더
| 헤더 이름 | 헤더 타입 | 설명 |
|:------------|:-------|-------------------------|
| From | 요청 | 사용자의 이메일 주소 |
| User-Agent | 요청 | 사용자의 브라우저 |
| Referer | 요청 | 사용자가 현재 링크를 타고 온 근원 페이지 |
> From 헤더
사용자의 이메일 주소를 포함
고유한 이메일 주소를 갖기 때문에 이론상 From헤더로 사용자를 식별할 수 있다.
악의적 서버가 이 이메일 주소들을 모아 스팸메일을 발송할 수 있는 문제가 있다.
로봇이나 스파이더는 본의 아니게 웹 사이트에 문제를 일으킨 경우, 항의 메일을 보낼 수 있도록
From헤더에 이메일 주소를 기술한다고 함
> User-Agent 헤더
사용자가 쓰고 있는 브라우저의 이름과 버전정보, 등등을 서버에게 알려준다.
이는 특정 브라우저에게 특화된 컨텐츠를 최적화하는데 도움을 줄 수 있지만,
특정 사용자들을 식별하는 데는 큰 도움이 되지 않는다.
- 헤더 예시
<img width="904" alt="스크린샷 2022-01-08 오후 1 36 08" src="https://user-images.githubusercontent.com/74235102/148631546-27fa5967-75df-4055-b7aa-a8041352bf65.png">
> Referer 헤더
사용자가 현재 페이지로 유입하게 한 웹페이지의 URL을 가리킨다.
<img width="220" alt="스크린샷 2022-01-08 오후 1 45 45" src="https://user-images.githubusercontent.com/74235102/148631796-b615f35b-9b08-40c7-86dc-75d69e2bbf69.png">
이 헤더로 이전에 어떤 페이지를 방문했었는지 알 수 있다.
`왜?` - 여기까지 들어오기 직전의 URL을 파악할 수 있기 때문에 유추할 수 있게 된다.
---
하지만 이 세가지 헤더로 확실하게 뭔가를 식별하기엔 정보가 부족함.
## 클라이언트 IP 주소
사용자가 확실한 IP 주소를 가지고 있고, 그 주소가 바뀌지 않고, 웹 서버가 요청마다
클라이언트 IP를 알 수 있다면 문제없이 동작한다.
### 약점
**클라이언트 IP 주소는 사용자가 아닌, 사용하는 컴퓨터를 가리킴.**
여러 사람이 이용하는 경우 그들을 식별할 수 없다.
**인터넷 서비스 제공자는 동적으로 IP주소를 할당**
그렇기 때문에 사용자를 IP 주소로 식별할 수 없음
**보안을 강화하고 부족한 주소들을 관리하려고 NAT 방화벽을 통해 인터넷을 사용함.**
클라이언트의 실제 IP 주소를 방화벽 뒤로 숨기기 때문에 식별할 수 없음
**HTTP 프락시와 게이트웨이는 원서버에 새로운 TCP 연결**
이렇게 되면 실제 IP주소가 아닌 프락시의 IP주소를 보게 됨
## 사용자 로그인
IP 주소로 식별하는 수동적 방식보다,
웹 서버는 사용자 이름과 비밀번호 인증을 요구하여 명시적으로 식별할수 있다.
`WWW-Authenticate`, `Authorization` 헤더를 사용하여 사용자 이름을 전달하는 체계를 갖고 있음.
자세한 내용은 12장에서 다룰 예정
## 뚱뚱한 URL
어떤 웹 사이트는 사용자의 URL마다 버전을 기술하여 사용자를 식별하고 추적했다.
> 뚱뚱한 URL이란?
사용자의 상태 정보를 포함하고 있는 URL
사용자와 관련된 정보를 찾아서 밖으로 향하는 모든 하이퍼링크에 정보를 포함하기 때문에
뚱뚱한 URL이 되고,
이 뚱뚱한 URL은 심각한 문제들이 있다.
### 못생긴 URL
브라우저에 보이는 뚱뚱한 URL은 새로운 사용자에게 혼란을 준다.
### 공유하지 못하는 URL
당연한 얘기인것은, 이 뚱뚱한 URL에 사용자에 관련된 정보들이 포함되어 있다.
그렇기에 공유하는 순간 내 개인정보들도 같이 공유한다는 것이 된다.
### 캐시를 사용할수 없음
URL로 만드는 것은, 계속해서 요청되는 URL이 변경되기 때문에 기존 캐시에 접근할 수 없다.
### 서버 부하 가중
서버는 뚱뚱한 URL에 해당하는 HTML 페이지를 다시 그려야 한다.
### 이탈
URL에 정보들이 추가된것만 사용해야 문제없이 동작한다.
하지만 중간에 사용자가 이탈하게 되면, 진행상황들이 다 리셋이 되는 경우가 발생할 것이다.
### 세션 간 지속성의 부재
특정 URL을 저장해놓지 않는 이상은, 로그아웃하게 되면 정보를 전부 잃는것이 된다.
## 쿠키
쿠키는 사용자를 식별하고 세션을 유지하는 방식 중, 현재 가장 널리 사용하는 방식
쿠키는 넷스케이프에서 개발했지만, 지금은 모든 브라우저에서 지원한다.
쿠키는 캐시와 충돌할 수 있어서, 대부분의 캐시나 브라우저는 쿠키에 있는 내용물을
캐싱하지 않는다.
### 쿠키의 타입
쿠키는 세션쿠키, 지속쿠키 두가지 타입이 존재
세션 쿠키 - 사용자가 브라우저를 닫으면 삭제되는 쿠키
지속 쿠키 - 삭제되지 않고 더 길게 유지될 수 있는 쿠키
두개의 차이점은 **파기되는 시점**
파기까지 남은 시간인 `Expires` 또는 `Max-Age` 파라미터가 없다면 세션 쿠기가 된다.
### 쿠키 동작
사용자가 웹 사이트에 방문하면, 웹사이트는 서버가 사용자에게 할당한 값들을 모두 읽을 수 있다.
쿠키는 임의의 이름=값 형태의 리스트를 가지고, `Set-Cookie` or `Set-Cookie2(확장 헤더)`와 같은 HTTP 응답 헤더에 기술되어
사용자에게 전달 된다.
### 쿠키 상자: 클라이언트 측 상태
쿠키의 기본은 브라우저가 서버 관련 정보를 저장하고, 사용자가 해당 서버에 접근할 때 마다
그 정보를 함께 전송하게 하는 것
브라우저가 쿠키 정보를 저장할 책임이 있는데 이게 클라이언트 측 상태 = `HTTP 상태 관리 체계`
#### 구글 크롬 쿠키
<img width="1226" alt="스크린샷 2022-01-13 오후 10 59 56" src="https://user-images.githubusercontent.com/74235102/149343821-0261788e-579d-4551-9965-bfc04e3f5625.png">
### 각 사이트마다 다른 쿠키
브라우저는 수백 수천 개의 쿠키를 가지고 있을 수는 있지만,
브라우저가 쿠키 전부를 모든 사이트에 보내지는 않는다.
1. 모두 전달하면 성능이 크케 저하
2. 특정 서버에 특화된 이름=값 쌍을 포함하기 때문에 인식하지 않는 무의미한 값 존재
3. 특정 사이트에서 제공된 정보를 다른 사이트에서 가져갈 수 있어 개인적인 정보 문제 존재
#### 쿠키 도메인 속성
`Set-cookie: user="lsj8367"; domain="sprout.or.kr"`
`sprout.or.kr` 도메인에 `user="lsj8367"`을 전달한다라는 의미
#### 쿠키 Path 속성
Path 속성으로 해당 경로쪽에 속하는 페이지만 쿠키를 전달하게 하는 속성
## Version 0 쿠키
넷스케이프 쿠키
Set-Cookie 속성
- 이름=값
- **필수 속성**
- 이름, 값 둘다 큰따옴표로 감싸지 않은, `;`, `,`, `=`, 공백 을 포함하지 않는 문자열
- Expires
- 선택적 속성
- 쿠키의 생명주기를 가리키는 날짜 문자열
- 이 일자에 다다르면 그 쿠키는 삭제됨
- 사용할 수 있는 타임 존 = GMT
- 형식 : `요일, DD-MM-YY HH:MM:SS GMT`
- 명시하지 않으면 사용자 세션이 끝날 때 파기
- Domain
- 선택적 속성
- 속성에 기술된 도메인을 사용하는 호스트만 쿠키를 전송
- 명시되어 있지 않다면, `Set-Cookie` 응답을 생성한 서버의 호스트명을 사용
- Path
- 선택적 속성
- 서버에 있는 특정 URL만 쿠키 할당
- 경로를 명시하지 않으면, `Set-Cookie` 응답을 전달하는 URL의 경로 사용
- Secure
- HTTP가 SSL 보안 연결을 사용할 때만 쿠키 전송
## Version 1 쿠키
Set-Cookie2 속성
- 이름=값
- **필수 속성**
- `$` 는 예약된 문자이므로 쿠키 이름은 `$`로 시작하면 안된다.
- Version
- **필수 속성**
- 쿠키 명세 버전을 가리키는 정수 값
- Comment
- 선택적 속성
- 서버가 쿠키를 사용하려는 의도 기술
- 인코딩 반드시 UTF-8
- CommentURL
- 선택적 속성
- 쿠키 사용 목적과 정책에 대해 상세하게 기술된 URL 링크 제공
- Discard
- 선택적 속성
- 이 속성이 있다면, 클라이언트 프로그램 종료될 때 클라이언트가 해당 쿠키를 삭제
- Domain
- 선택적 속성
- 기술된 도메인에 해당하는 서버 호스트들에게만 쿠키 전송
- Max-Age
- 선택적 속성
- 쿠키 생명주기 `초 단위`
- 클라이언트는 HTTP/1.1 수명 계산 규칙에 따라 수명을 계산해야 한다
- Path
- 선택적 속성
- 서버에 있는 특정 문서에만 쿠키 할당
- Version 0 과 동일
- Port
- 선택적 속성
- 값 없이 속성의 키워드만 기술할 수 있고, 포트를 한개 이상 콤마를 이용하여 구분 기술할 수 있음
- Secure
- HTTP가 SSL 보안 연결을 사용할 때만 쿠키가 전송
## 쿠키와 세션 추적
쿠키는 웹 사이트에 수차례 트랜잭션을 만들어내는 사용자를 추적하는데 사용한다.
## 쿠키와 캐싱
쿠키 트랜잭션과 관련된 문서를 캐싱하는 것을 주의해야 한다.
> 이유?
이전 사용자의 쿠키가 다른 사용자에게 할당되거나, 개인정보까지도 노출이 될 수 있다.
### 캐시를 다루는 기본 원칙
**캐시되지 말아야 할 문서가 있다면 표시해라**
문서가 `Set-Cookie` 헤더를 제외하고 캐시해도 되는 경우라면,
그 문서에 명시적으로 `Cache-Control: no-cache="Set-Cookie"` 를 기술하여 명확히 표시한다.
캐시를 해도 되는 문서에 `Cache-Control: public` 을 사용하면 웹의 대역폭을 더 절약시켜준다.
**Set-Cookie 헤더를 캐시 하는 것에 유의하라**
같은 `Set-Cookie` 헤더를 여러 사용자에게 보내게 되면, 사용자 추적에 실패할 것
어떤 캐시는 `Set-Cookie` 헤더를 응답 저장전에 제거한다.
이런 문제를 방지하기 위해서 모든 요청마다 캐시가 원 서버와 재검사를 시켜 `Set-Cookie` 헤더 값을 주어
이 문제를 개선할 수 있다.
`Cache-Control: must-revalidate, max-age=0`
**Cookie 헤더를 가지고 있는 요청을 주의하라**
요청에 Cookie 헤더와 같이 넘겨지면, 결과가 개인정보를 담고 있을 수 있다.
## 쿠키, 보안 그리고 개인정보
쿠키를 사용하지 않도록 비활성화도 가능하기 때문에, 이 자체가 보안상으로 위험하다고 할수는 없다.
개인정보를 다루거나 사용자를 추적하는 기술은 잘못된 의도로 사용할 수 있기 때문에 주의하여야 한다.
**가장 큰 오용중 하나는 사용자 추적을 위한 지속 쿠키**이다.
개인 정보를 누가 받는지 명확하게 파악하고, 개인정보 정책을 유의한다면
위험성 보다는 세션 조작이나 트랜잭션상 편리함이 크다.
HTTP완벽가이드
- 클라이언트 식별과 쿠키 2022.08.10
클라이언트 식별과 쿠키
2022. 8. 10. 19:25
728x90
728x90