Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs] Final Assignments #53

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 205 additions & 0 deletions contents/minjunseong/TIL4(Cookie,Session).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# Appcenter Basic Course Study Fin _ Cookie & Session

### 😎 쿠키와 세션은 무엇인가?
```
출처 1 : https://velog.io/@octo__/%EC%BF%A0%ED%82%A4Cookie-%EC%84%B8%EC%85%98Session
출처 2 : https://velog.io/@wlwl99/HTTP%EC%9D%98-%ED%8A%B9%EC%A7%95
출처 3 : https://interconnection.tistory.com/74
출처 4 : https://velog.io/@seongguk/%EC%BF%A0%ED%82%A4-%EC%84%B8%EC%85%98-%EC%BA%90%EC%8B%9C-%EB%B9%84%EA%B5%90-%EC%A0%95%EB%A6%AC
출처 5 : https://dev-coco.tistory.com/61
```
#### HTTP 프로토콜의 특징
- HTTP는 **Connectionless(비연결지향)**, **Stateless(무상태)** 특징을 가지고 있다.
- 비연결지향이란, Response와 Request를 주고받을 때에만 통신(TCP/IP)을 유지하고, 응답을 주고받은 뒤에는 TCP/IP연결을 해지한다. 이러한 특성으로 인해 최소한의 자원으로 서버를 유지한다.
- 단, 이는 HTTP 1.0모델에서의 얘기이다. 웹사이트의 정보량은 상당해지며, 계속해서 HTML, CSS, JS, 이미지자료 등을 계속 주고받기에는 비효율적인 특성이다. (각 자원을 다운받기 위해 연결과 끊김을 계속 반복하게되는 비효율적 구조)
- HTTP 1.1모델에서는 Persistant Connections라는 특성을 추가하여, HTTP 지속 연결에서는 연결이 이루어지고 난 뒤 각각의 자원들을 요청하고, 모든 자원에 대한 응답이 돌아온 후에 연결을 종료한다. (컴퓨터네트워크 시간에 배울테지만, Keep-Alive Option을 활용한다.)
- 어쨌거나 비연결지향의 특성을 띄고있다.
- 이 외에도 세션과 토큰이 중요하게 여겨지는 이유인 '무상태'가 있다.
- 무상태란, 서버가 클라이언트의 상태를 보존하지 않음으로써, 응답과 요청을 독립적으로 유지하도록 한다.
- 이로 인해 클라이언트는 계속해서 추가 데이터를 전송해야되는 상태가 되었다.
- 하지만 로그인, 클라이언트의 맞춤 정보 등의 상태를 유지해야하는 상황이 있다. 혹은 내가 장바구니에 열심히 사고싶은걸 담았는데.. 몽땅 사라져버리는 대참사도 방지해야한다.
- **이러한 통신과정의 한계를 극복하기 위해, 브라우저 쿠키, 서버 세션 및 토큰의 개념이 활용되기 시작했다.**

#### 쿠키는 무엇일까요?
~~내가만든 쿠키 너를위해 구웠지~~
- HTTP의 일종으로 사용자가 어떤 웹 사이트를 방문할 경우, 해당 사이트가 사용하고 있는 서버에서 사용자의 컴퓨터에 저장하는 작은 기록 정보 파일이다.
- HTTP에서 클라이언트의 상태정보를 쿠키 형태로 클라이언트 PC에 저장하였다가 필요 시 정보를 참조하거나 재사용할 수 있다.
- 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다는 특징이 있다.
- Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있다.
- 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 전송합니다.
- 데이터가 서버가 아닌 사용자의 PC에 저장되기 때문에, 임의로 고치거나 지울 수 있고, 가로채기도 쉬워 보안이 취약하다는 단점이 있다.
- **따라서, 쿠키에는 민감하거나 중요한 정보를 담는 것은 위험하다.**

#### (추가) 쿠키의 종류
> #### 🥨 Session Cookie
> 임시 쿠키라고 불리는 세션 쿠키는 **임시 메모리에 저장**이 되며 만료일이 없다.
> 사용자가 웹사이트를 접속 시 생성되며 **브라우저를 닫을 때 영구적 삭제**

> #### 🥨 Persistant Cookie
> 사용자의 재방문에서 사용자를 기억하고 식별하는 데에 사용된다.
> 로그인 유지 및 사용자 인증을 처리한다.
> 개인 데이터 노출 가능성이 있어 보안상 좋지 않다.
> 주로 유저의 이전 방문상태를 추적하기 위해 사용하기 때문에 Tracking cookie라고 부르기도 한다.
> 쉽게 생각하면 카카오톡 PC버전에서 로그인할 때 자동로그인 걸어두는것과 같은 개념이다.

> #### 🥨 Secure Cookie
> 웹브라우저와 웹서버가 **HTTPS로 통신할 경우**에만 웹브라우저가 쿠키로 전송한다.
> 항상 **암호화**하기 때문에 **쿠키가 노출될 가능성이 줄어든다.**

> #### 🥨 Third-Party Cookie
> **접속한 사이트 도메인에서 발행되지 않은 쿠키**는 모두 서드 파티 쿠키(서브 도메인 예외)
> 주로 **광고 목적**으로 사용. *운동기구 사이트를 많이 사용하게 되면 운동기구 광고가 계속 화면에 나타나는 것!!

#### 세션이란 무엇일까요?
- 클라이언트로부터 오는 일련의 요청을 하나의 상태로 보고 그 상태를 일정하게 유지하는 기술이다.
- 클라이언트가 웹 서버에 접속해있는 상태가 하나의 단위
- 세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리
- 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지
- 클라이언트가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는 데 이것이 세션 ID
- 세션 ID로 클라이언트를 구분해서 클라이언트의 요구에 맞는 서비스를 제공
- 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 됨 -> Traffic 과도하게 몰림 -> 성능 저하 -> 서버 펑!
- **로그인 작업과 같이 주로 보안상 중요한 상황일때 세션을 이용!**

#### Session & Cookie : Request & Response Flow
1. 클라이언트가 서버에 Request → 서버는 세션을 생성 + 고유한 세션 ID를 발급.

2. 서버는 세션 ID를 쿠키에 설정한 뒤 클라이언트로 Response.

```http
HTTP/1.1 200 OK
Set-Cookie: sessionId=1q2w3e4r; HttpOnly; Secure
# 참고 : HttpOnly는 Http통신외에는 쿠키에 접근하지 못하도록 하는 Secure Coding의 일종이다.
# 아까 언급했던 XSS공격으로부터 편안해질 수 있다.
```

3. 클라이언트는 다음 요청 시, 이 쿠키(세션 ID)를 포함하여 서버에 전송.

```http
GET /todos HTTP/1.1
Cookie: sessionId=abc123
```

4. 서버는 세션 ID를 통해 클라이언트를 식별하고, 필요한 데이터를 제공.



#### Difference of Session & Cookie
- 쿠키와 세션은 비슷한 역할을 하며, 동작 원리도 비슷하다. 그 이유는 세션도 결국 쿠키를 사용하기 때문.
- 큰 차이점은 사용자의 정보가 저장되는 위치이다. 쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용한다.
- 보안 면에서 세션이 더 우수하다.
- 쿠키 같은 경우는, XSS 공격에 취약하며, 악성 스크립트로 클라이언트의 데이터를 Sniffing할 수 있다.
- 세션 같은 경우는, 데이터 자체가 서버에 저장되므로 비교적 안전하다 (그러나, 쿠키에 수집된 Session-ID정보가 탈취당할 가능성이 있으므로 주의해야하기도 한다.)
- 라이프 사이클은 쿠키도 만료기간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 정보가 유지될 수 있다. 또한 만료기간을 따로 지정해 쿠키를 삭제할 때까지 유지할 수도 있다.
- 반면에 세션도 만료기간을 정할 수 있지만, 브라우저가 종료되면 만료기간에 상관없이 삭제된다.
- 속도 면에서 쿠키가 더 우수하며, 쿠키는 쿠키에 정보가 있기 때문에 서버에 요청 시 속도가 빠름.
- 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 낸다.

---

### 😎 세션 기반 인증과 토큰 기반 인증

#### Session-Based Authorization Flow
- 로그인 요청: 클라이언트가 서버에 사용자 인증 정보(ID/PW)를 전송.
```http
POST /login
{
"id": "asdf",
"pwd": "qwer"
}
```
- 세션 생성: 서버가 사용자 인증 후 세션을 생성하고, 고유한 세션 ID 발급.
- ** 세션 ID를 클라이언트 쿠키에 저장하도록 Set-Cookie 헤더로 응답
```http
HTTP/1.1 200 OK
Set-Cookie: sessionId=a1s2d3
```
- 세션 ID 전달: 클라이언트는 세션 ID를 쿠키에 저장.
- 인증된 요청: 클라이언트는 이후 요청 시 세션을 서버가 확인하기 위해 세션 ID를 포함.
```http
HTTP/1.1 200 OK
GET /todos
Cookie: sessionId=a1s2d3
```
- 서버의 처리: 서버는 세션 ID를 통해 사용자를 인증하고 요청 처리.

#### Token-Based Authorization Flow
1. 로그인 요청: 클라이언트가 서버에 사용자 인증 정보(ID/PW)를 전달.
```http
POST /login
{
"id": "asdf",
"pwd": "qwer"
}
```
2. 토큰 발급: 서버는 인증 후, JWT(JSON Web Token) 같은 토큰을 발급.
```http
HTTP/1.1 200 OK
{
"accessToken": "암호화 알고리즘을 이용해 해싱한 보안 키"
}
```
3. 토큰 저장: 클라이언트는 토큰을 로컬 스토리지, 세션 스토리지, 혹은 쿠키에 저장.
4. 인증된 요청: 클라이언트는 요청 시 토큰을 HTTP 헤더(Authorization 부분)에 포함.
```http
GET /todos
Authorization: "인증 방식" "암호화 알고리즘을 이용해 해싱한 보안 키"
```
5. 서버 처리: 서버는 토큰의 유효성을 검증하고 요청 처리.

#### (추가) JSON Web Token (JWT)
**토큰 기반 인증**시에는 이 JWT를 활용하게 된다.

JWT는 헤더, 페이로드, 시그니쳐의 구조로 1q2w3e.q1w2e3.qqee2와 같이 (.)을 통해 구분이 된다.

- 헤더 : 어떤 알고리즘으로 암호화 할 것 인가?
- 페이로드 : 최소한의 데이터, 아이디나 PW와 같이 민감한 데이터를 포함해선 안된다. (누구나 열람 가능)
- 시그니쳐 : 보안상 있는 부분. 토큰의 무결성을 확인하기 위함이다. Header와 Payload + 암호화된 키의 조합으로 구성되어있어 토큰 교환 시의 검증할 수 있는 수단이다.
- *** 참고 : 컴퓨터 보안에서의 페이로드와, JWT에서의 페이로드는 조금 다른 개념이다.

#### 각 헤더의 처리
|Session-Based Auth|Token-Based Auth|
|------------------|----------------|
|쿠키를 사용하여 sessionId값을 이용|Authorization 헤더에 어떤 인증 방식인지 + 서버로부터 발급받은 보안 키를 포함해서 처리|

#### Token은 어디에 관리되는가?
1. 로컬 스토리지
말 그대로 클라이언트(Browser)의 PC 내부에 Key-Value 형태로 저장된다.
브라우저를 닫아도 데이터가 유지되는 특징이 있다. 클라이언트 PC의 내부에 저장하다보니 용량을 큰 것도 저장 가능. 그러나 보안의 결함 때문에 로컬 스토리지로 토큰을 관리하는건 피하는 편이다.

2. 세션 스토리지
사용자가 세션을 유지하는 동안에만 유지되는 저장 공간으로, 브라우저 '탭'별로 관리된다. 인터넷 창 닫으면 로그인 정보가 날라 가는것도 여기서 비롯된게 아닐까 싶다.

3. 쿠키
HTTP를 활용하여 서버에 포함시켜 주고받을 수 있는 수단으로 쓸 수도 있다.

---

### 😎 실무에서는 어떤 인증 방식을 사용할까?

#### RESTful API로 설계된 서비스에서는 토큰 기반 인증을 주로 사용한다.
- 토큰 기반 인증의 장점은 서버의 확장성(클라이언트가 데이터를 관리하기에 서버 입장에선 편안) + 무상태성이다.
- 토큰 기반 인증을 통해 서비스를 이용하면, 클라이언트가 독립적으로 서버에 통신할 수 있다.
- Instagram, Facebook과 같은 SNS는 대부분 토큰 기반 인증 방식을 활용한다.

#### 민감한 데이터들이 오고가는 서비스에선 세션 기반 인증을 주로 사용한다.
- 예를 들면 군대 혹은 사내 인트라넷, SNS의 관리자들만 접근할 수 있는 페이지 등은 세션 기반 인증을 활용하는것이 좋다.
- 말고도 짧은 수명을 가진 애플리케이션 (클라이언트가 오래 머무를 필요가 없는 페이지) 은 세션 기반 인증을 활용할 수 있다.
- 왜냐하면 서비스 구축 입장에서도 더 간편하고, 보안상 유리하기 때문이다.
- 이와 같이 '적은 작업', '한 번의 작업 (넥슨 OTP와 같이 잠깐동안만 인증하는 그런 페이지)'일 때에는 세션 기반 인증을 주로 활용한다.

**Conclusion : 결국 둘 다 쓴다는 말이다.**


---

### 😎 Cache란?
#### 정의
자주 사용하는 데이터나 연산 결과를 더 빠른 저장소(주로 메모리)에 임시로 저장해, 이후 동일한 요청이 발생했을 때 데이터를 빠르게 제공하는 시스템을 뜻한다.

#### 왜 쓰는거지?
접근 시간에 비해 원본 데이터에 접근하는 시간이 오래 걸리는 경우에 사용한다. 원 서버(origin server)에 대한 요청을 줄여주어, 더 빨리 응답할 수 있게 된다. 하지만, 원본 데이터가 수정되면 캐시가 의미가 없어지므로 교체되어야 하며, 메모리 사용량이 높아지는 결과가 생긴다.

#### 그럼 캐시는 어떻게 교체가 이루어지나요?
1. LRU(Least Recently Used) : 메모리에 남아 있는 캐시 중 가장 오래동안 사용되지 않은 캐시를 새로운 캐시로 교체
2. LFU(Least Frequently Used) : 가장 적게 참조된 페이지를 교체한다
3. FIFO(First In First Out) : 가장 먼저 들어간 데이터를 교체한다.