728x90

# 클라이언트 식별과 쿠키

이 장에서는 서버가 통신하는 대상을 식별하는데에 사용하는 기술을 알아본다.

## 개별 접촉

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 헤더와 같이 넘겨지면, 결과가 개인정보를 담고 있을 수 있다.

## 쿠키, 보안 그리고 개인정보

쿠키를 사용하지 않도록 비활성화도 가능하기 때문에, 이 자체가 보안상으로 위험하다고 할수는 없다.

개인정보를 다루거나 사용자를 추적하는 기술은 잘못된 의도로 사용할 수 있기 때문에 주의하여야 한다.

**가장 큰 오용중 하나는 사용자 추적을 위한 지속 쿠키**이다.

개인 정보를 누가 받는지 명확하게 파악하고, 개인정보 정책을 유의한다면

위험성 보다는 세션 조작이나 트랜잭션상 편리함이 크다.

728x90
728x90

웹 캐시

웹 캐시 또는 HTTP 캐시 라고 하는데,

이 캐시는 서버와 불필요한 네트워크 통신을 줄이기 위해서 임시 저장한

정보들을 바로 뿌려주는 기술이다.

웹 캐시가 자신의 저장소 내에 요청된 리소스를 가지고 있다면, 그 요청을 가로채

원래라면 서버에서 리소스를 가져오겠지만, 리소스의 복사본(프록시) 를 통해 데이터를 가져오게 된다.

성능이 향상되는건 말할 것도 없지만, 이 리소스가 영원히 변하지 않는 것은 아니기 때문에

가지고 있던 값이 변하기 전까지만 캐시로 유지하고 더 이상은 캐싱을 하지 않아야 한다.

사설 브라우저 캐시

이 캐시는 한 사용자 전용의 캐시이다.

예로, 크롬 브라우저를 켰을때 브라우저 자체는 이 사용자만의 캐시를 고유하게 갖고 있다.

이게 사용자마다의 개개인의 캐시로 기록이 되어있기 때문에 사설 브라우저 캐시라고 하는 것이다.

공유 프록시 캐시

내가 이해한 바로는 어떤 API를 호출하는 작업이 있을 때

자기 자신뿐 아니라, 같은 API를 누구든 호출할 때 재사용되기 때문에 그 재사용되는 응답을 저장하는 캐시이다.

유효성

사실상 캐시에 저장된다고 한다면 그 리소스가 변경, 만료기간이 없다고 할 때,

영원히 캐시로만 서비스가 될 수도 있다.

그렇지만 캐시의 공간은 유효하기 때문에 주기적으로 제거가 된다.

동작과정

스크린샷 2021-12-10 오전 10 17 43

Cache-Control 헤더의 max-age값은 만료 시간을 의미한다.

1번 그림

1번그림은 캐시가 없을 때, /doc의 url로 GET 요청을 하면

캐시가 없는 상태이므로, 서버에서 리소스를 조회한다.

그 이후에 저장된 캐시가 없었기 때문에, 이 리소스를 바탕으로 캐시를 하나 생성하고

클라이언트에 Response값을 내려준다.

2번 그림

1번 그림에서 10초가 지난뒤에 다시 /docGET요청을 보내본다.

근데 설정한 만료시간은 100초 이므로 10초는 만료시간 내에 존재한다.

그래서 서버로 리소스 찾는 명령을 보내지않고 캐시에 저장된 데이터를 클라이언트에게 돌려준다.

3번 그림

설정한 만료 시간 (100초) 를 지난 후에 같은 방식으로 요청을 보낸다.

이번에는 만료 시간이 지났기 때문에 캐시는 한번 검증을 해야한다.

변경된 값이 있는지를 체크해야 한다

그다음에 변경 사항이 없다면 304 상태 코드로 수정 사항이 없다는 것을 알리면서

시간을 갱신한 후 클라이언트로 돌려주는 과정이 되겠다.

캐시 검증

위 3번 그림에서 봤듯, 캐시의 만료시간이 지나면 문서를 다시 서버에 요청하여 가져와야 하는데

두가지 옵션이 있다.

ETags

ETags는 캐시 데이터와 함께 헤더에 고유 식별자를 붙여서 내려보내 주게 된다.

HTTP/1.1 200 OK
Cache-Control: max-age:100
Age: 0
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

이런식으로 데이터가 내려가게 된다.

검증할 때에는 ETag 헤더값으로 데이터를 식별하고, 만료되어 새로운 캐시를 저장할 때에는

마찬가지로 ETag의 값도 새로 갱신하고 내려주게 된다.

아래는 깃허브에서 스프링 캐시에 대한 학습을 진행해보았다.

깃허브 바로가기

728x90

'CS' 카테고리의 다른 글

ALU 구현  (0) 2022.08.09
불 연산 회고  (0) 2022.08.09
불 논리 정리 2  (0) 2022.08.09
불 논리 회고  (0) 2022.08.07
728x90

HTTP란?

HTTP(Hyper Text Transfer Protocol) 텍스트 기반 통신 규약으로써,

인터넷에서 데이터를 주고받을 수 있는 프로토콜입니다.

HTTP는 신뢰성 있는 데이터 전송 프로토콜을 사용하는데

TCP 프로토콜에서는 데이터 송수신을 위해 클라이언트와 서버의 소켓이 연결되어 있어야 하며, 데이터가 유실되면 데이터

재전송을 요청함으로써 신뢰성을 보장합니다.

즉, 신뢰성 있는 데이터 전송이 가능하다는 장점으로 인해 HTTP, FTP, TELNET 등 대부분의 응용 계층 프로토콜의

전송 계층으로 사용 됩니다.

이렇기 때문에 인터넷의 결함이나 약점에 대한 걱정 없이 고유의 기능을 구현하는데에만 집중이 가능합니다.

웹 클라이언트와 서버

웹 콘텐츠들은 웹 서버에 존재합니다. 웹 서버는 HTTP로 통신을 한다고 했었기 때문에, HTTP서버 라고도 합니다.

웹 서버는 인터넷의 데이터를 저장하고, 클라이언트가 요청한 데이터를 제공해줍니다.

쉽게 설명하면 프론트단에서 Request(요청) 값을 보내면 서버쪽에서 Response(응답) 객체를 내려주는 원리라고

생각하면 되겠습니다.

이것이 바로 World Wide Web(통칭 WWW) 의 기본 요소입니다.

리소스

웹 서버는 웹 리소스들을 관리하고 제공합니다.

원초적인 이 웹 리소스는 웹 서버 파일 시스템의 정적 파일입니다.

이 정적 파일이라 함은, HTML파일부터 시작하여, 이미지파일 등등 모든 종류의 파일이 여기에 포함됩니다.

이런 정적파일이 주가 되기는 하지만, 무조건적으로 정적 파일일 필요는 없습니다.

이 동적 리소스인 경우에는 사용자마다, 시간, 정보 등등에 따라 각기 다른 콘텐츠들을 제공합니다.

미디어 타입

미디어 타입은 서버에서 메소드인자에 많이 들어간것을 생각해보면 됩니다.

대표적인 예가 바로

setContentType(MediaType.APPLICATION_JSON) 입니다.

인터넷은 수천가지 데이터 타입들을 다루기 때문에, HTTP에서는 웹에서 전송되는 객체 각각에 MIME이라는

데이터 포맷 타입을 붙이게 됩니다. 이 MIME은 전자메일 시스템에서 주로 사용을 했었는데,

각 문서와 함께 올바른 MIME 타입을 전송하도록, 서버가 정확히 설정하는 것이 중요합니다.

브라우저들은 리소스를 내려받았을 때 해야 할 기본 동작이 무엇인지를 결정하기 위해 MIME 타입을 사용합니다.

문법

MIME 타입의 구조는 주타입 / 부타입 으로 이루어져 있습니다.

이러한 예시들이 있습니다.

  • application/json
  • text/html
  • image/jpeg

URI (Uniform Resource Identifier)

웹 리소스는 각기 고유한 이름을 가지고 있기 때문에, 클라이언트는 해당 리소스를 지목하여 호출할 수가 있습니다.

글에대한 리소스 URI라면 이렇게 표현이 가능합니다.

https://lsj8367.github.io/spring/Spring-Filter-Interceptor/

  1. https 프로토콜을 사용해서
  2. lsj8367.github.io 로 이동한 후
  3. spring/Spring-Filter-Interceptor 에 해당하는 리소스를 가져와줘!

하면 이제 해당하는 글에 대한 포스팅을 보여주게 될 것입니다.

728x90

'CS' 카테고리의 다른 글

불 논리 정리 2  (0) 2022.08.09
불 논리 회고  (0) 2022.08.07
불 논리 정리  (0) 2022.08.07
재귀 알고리즘  (0) 2022.08.06

+ Recent posts