Skip to content
Open
Show file tree
Hide file tree
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
143 changes: 143 additions & 0 deletions keyword/chapter09/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
- 세션과 토큰의 차이는?

> 가장 핵심적인 차이는 “인증 정보를 서버에 저장하느냐, 아니면 클라이언트가 직접 들고 다니느냐”에 있다.
>

**[세션 방식: 서버 중심]**

세션 방식은 사용자의 **로그인 상태 정보를 서버(메모리, DB, Redis 등)에 저장**하고 관리하는 방식이다.

**<동작 방식>**

1. 사용자가 로그인하면 서버는 사용자의 세션 정보를 생성하고, 이를 구별할 수 있는 고유한 세션 ID를 발급한다.
2. 서버는 이 세션 ID를 클라이언트에게 전송하며, 브라우저는 이를 보통 쿠키에 저장한다.
3. 이후 클라이언트는 요청을 보낼 때마다 쿠키에 세션 ID를 담아 보낸다.
4. 서버는 요청에 담긴 세션 ID가 서버의 세션 저장소에 있는지 확인하고 사용자를 인증한다.

**<장 단점>**

- **보안성/통제력**: 서버가 세션 정보를 직접 가지고 있어, 특정 사용자의 세션을 강제로 만료시키거나 제어하기 쉽다.
- ex) 중복 로그인 방지, 로그아웃 처리
- **데이터 크기**: 클라이언트는 오직 짧은 세션ID만 주고 받아 네트워크 부하가 적다.
- **서버 확장성 문제:** 사용자가 많아질 수록 서버 메모리나 DB에 부담이 커지며, 서버를 여러 대 두는 분산 환경에서는 서버들이 데이터를 공유할 수 있도록 별도의 세션 서버를 구축해야한다.

**[토큰 (Token, JWT) 방식: 클라이언트 중심]**

****토큰 방식은 인증에 **필요한 정보를 토큰 자체에 인코딩하여** 클라이언트가 직접 들고 있도록 하는 방식이다.

**<동작 방식>**

1. 사용자가 로그인하면 서버는 사용자의 인증 정보, 권한, 만료 시간 등을 담은 **토큰**을 생성한다. 이때 **서버만 알고 있는 비밀키**로 **토큰을 서명(Digital Signature)한다**.
2. 서버는 이 토큰을 클라이언트에게 전달한다.
3. 클라이언트는 로컬 스토리지, 세션 스토리지, 또는 쿠키 등에 토큰을 저장해 둔다.
4. 이후 요청을 보낼 때 HTTP 헤더(`Authorization: Bearer <토큰>`)에 이를 담아 보낸다.
5. 서버는 토큰을 받으면 별도의 DB 조회 없이, **자신의 비밀키로 토큰의 서명이 유효한지만 검증**하고 바로 인증을 승인한다.

**<장단점>**

- **무상태성과 확장성**: 서버는 클라이언트 상태를 저장하지 않는다. 서버가 여러 대로 늘어나도 비밀키만 공유하고 있다면 어떤 서버에서도 토큰 검증이 가능하다.
- **MSA 친화적**: 여러 서비스가 분리되어 있을 때, 하나의 토큰으로 여러 서비스에서 공통으로 인증을 처리하기 쉽다.
- **제어의 어려움**: 토큰이 1번 발급되면 만료될 때까지 강제 회수나 무효화가 어렵다. 이를 보완하기 위해 만료 기간이 짧은 Access Token과 이를 재발급하는 Refresh Token을 함께 사용한다.
- **데이터의 크기**: 토큰에 많은 정보를 담을수록 토큰의 크기가 커져 요청마다 네트워크 트래픽을 더 많이 소모한다.

- 엑세스 토큰과 리프레시 토큰이란?

> JWT 기반 토큰 방식의 가장 큰 약점인 “한 번 발급된 토큰은 만료될 때까지 서버가 강제로 무효화하기 어렵다.”는 점을 해결하기 위한 보안 전략으로 토큰을 나눠 사용하는 **이중 토큰 인증방식**이다.
>

**[엑세스 토큰 (Access Token)]**

- 사용자가 로그인되어 있는 동안, 인증이 필요한 서버의 API를 호출할 때 헤더에 실어 보내는 **실제 인증 토큰**이다.
- 보통 보안을 위해 **유효기간을 매우 짧게** 설정한다. (30분 ~ 2시간)
- 유효 기간을 짧게 하여 해커가 토큰을 탈취하더라도 금방 사용할 수 없게 되어 피해를 최소화할 수 있다.
- 대신 사용자는 **수시로 토큰을 갱신**해야 한다.

**[리프레시 토큰 (Refresh Token)]**

- 엑세스 토큰이 만료되었을 때, 사용자가 다시 로그인 창을 보지 않고 **새로운 엑세스 토큰을 안전하게 재발급받기 위해** 사용하는 토큰
- 유효기간을 상대적으로 길게 설정한다. (2주 ~ 한 달)
- 일반적인 API 요청에는 사용되지 않으며, **엑세스 토큰 재발급 API를 호출할 때만** 사용된다.

**[전체 인증 흐름]**

```markdown
1. 로그인 성공: 사용자가 로그인을 하면 서버는 액세스 토큰과 리프레시 토큰을 동시에 발급한다.

2. API 요청: 클라이언트는 평소에 액세스 토큰만 HTTP 헤더에 담아서 서버에 요청을 보낸다. 서버는 이를 검증하고 데이터를 준다.

3. 액세스 토큰 만료: 시간이 지나 액세스 토큰이 만료되면, 서버는 클라이언트에게 401 Unauthorized (또는 토큰 만료 에러 코드)를 반환한다.

4. 토큰 재발급 요청: 에러를 받은 클라이언트는 사용자가 모르게 보관하고 있던 리프레시 토큰을 담아 서버의 '토큰 재발급 API'로 요청을 보낸다.

5. 검증 및 재발급: 서버는 리프레시 토큰의 유효성을 검증한 뒤, 문제가 없다면 새로운 액세스 토큰을 만들어 클라이언트에게 다시 내려준다.

6. 요청 재시도: 클라이언트는 새로 발급받은 액세스 토큰을 저장하고, 실패했던 API 요청을 다시 보낸다. 사용자는 로그인 창을 다시 보지 않고 서비스를 계속 이용하게 된다.
```

<aside>
💡

**왜 리프레시 토큰은 서버에 저장할까?**

리프레시 토큰마저 탈취당하면 해커가 지속적으로 액세스 토큰을 발급받을 수 있기 때문에, 서버는 대개 리프레시 토큰을 DB나 Redis에 저장해 둔다.

만약 보안 위협이 감지되면 서버에서 해당 리프레시 토큰을 지워버림으로써 강제 로그아웃을 시킬 수 있는 최소한의 통제권을 확보하기 위함

</aside>

- OAuth 1.0과 OAuth 2.0의 차이는?

> 외부 애플리케이션에 사용자의 비밀번호를 노출하지 않고 안전하게 권한을 위임하기 위해 만들어진 인증 표준 프로토콜이다.
>

> OAuth 2.0은 1.0의 복잡한 암호화 계산 과정을 단순화하고, 다양한 환경에 맞춤형 인증 흐름을 제공하도록 재설계된 프로토콜이다.
>

**[OAuth 1.0]**

<암호화 방식과 디지털 서명>

- 모든 API 요청마다 **디지털 서명을 생성**해서 호환해야 한다.
- HMAC-SHA1 등의 알고리즘을 사용해 요청 메시지를 복잡하게 암호화해야 했기에 클라이언트와 서버 모두 **구현이 까다롭다**.
- HTTP 환경에서도 보안이 유지된다.

<토큰의 형태와 수명>

- 한 번 발급받은 Access Token은 만료 기간이 없는 경우가 많아, 토큰이 탈취되면 수동으로 무효화하기 전까지 영구적인 위협

<인증 흐름의 분화>

- 웹 브라우저 기반의 애플리케이션만을 염두에 두고 설계되었다.
- 따라서, 모바일 앱이나 단말기가 없는 환경에서는 적용하기 복잡하다.

<확장성: 서버 역할의 분리>

- 인증을 처리하는 서버와 실제 데이터를 제공하는 API 서버가 명확히 분리되지 않는 구조

**[OAuth 2.0]**

<암호화 방식과 디지털 서명>

- 복잡한 **디지털 서명 과정을 완전히 없앴다**.
- 통심 암호화 표준인 **HTTPS**에 보안을 전적으로 **위임**한다.
- 암호화 계산이 필요 없어져서 개발자들의 구현이 쉬워졌다.

<토큰의 형태와 수명>

- Access Token과 Refresh Token의 개념을 도입
- Access Token의 수명을 짧게 제한하고, Refresh Token을 통해 안전하게 재발급받도록 설계하여 보안성 보완
- 토큰 자체도 Bearer 토큰 형태를 사용한다.

<인증 흐름의 분화>

시나리오에 맞는 4가지 이상의 권한 부여 방식을 제공

- Authorization Code Grant: 전통적인 백엔드가 있는 웹 사이트용
- Implicit Grant: 백엔드가 없는 SPA(프론트 엔드 단독) 앱용
- Resource Owner Password Credentials Grant: 신뢰할 수 있는 퍼스트파티 앱용 (ID, PW 직접 입력)
- Client Credentials Grant: 사용자 개입 없이 서버 대 서버로 통신용

<확장성: 서버 역할의 분리>

- 인증 서버와 자원 서버의 역할이 개념적으로 명확히 분리되어 있다.
- 인증만 담당하는 서버를 따로 두고, 대규모 API 서버를 운영하는 MSA 등을 설계하기가 수월해졌다.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions mission/chapter09/mission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### 피어 리뷰

![에반_피어리뷰_제이의_워크북.png](./images/피어리뷰_PR리뷰_에반_9주차.png)