# OAuth 2.0 인증 흐름 완전 정복 – 서버‑사이드, PKCE, 디바이스 코드, 클라이언트 크레덴셜까지

*SEO 키워드: **OAuth 2.0**, **인증 흐름**, **PKCE** *

---

# # 📌 서론 – “왜 이렇게 복잡할까?”

최근 웹·모바일 서비스가 늘어나면서 **보안**은 선택이 아닌 필수가 되었습니다.

그 중심에 있는 것이 바로 **OAuth 2.0** 입니다.

하지만 “Authorization Code”, “PKCE”, “Device Code”, “Client Credentials” 같은 용어가 난무해 초보자는 어디서부터 손을 뻗어야 할지 막막합니다.

이 글에서는 **OAuth 2.0의 주요 인증 흐름**을 **쉽게** 이해할 수 있도록 **다이어그램**과 함께 단계별로 풀어냅니다.

> **핵심 포인트**

> 1️⃣ 인증 흐름마다 **누가, 무엇을, 언제** 하는지 구분한다.

> 2️⃣ 각 흐름이 **어떤 상황**에 최적화돼 있는지 기억한다.

> 3️⃣ 구현 시 **보안 체크포인트**를 놓치지 않는다.

---

# # 🧩 본론

## # 1️⃣ Authorization Code Flow (서버‑사이드 애플리케이션)

| 단계 | 설명 | 주요 파라미터 |

|------|------|--------------|

| 1. 사용자 → 클라이언트 | 로그인 버튼 클릭 → 인증 요청 URL 생성 | `response_type=code`, `client_id`, `redirect_uri`, `scope` |

| 2. 인증 서버 → 사용자 | 로그인 화면 제공 | – |

| 3. 사용자 → 인증 서버 | 아이디·비밀번호 입력 후 승인 | – |

| 4. 인증 서버 → 클라이언트 | `code`(인증 코드) 반환 (리다이렉트) | `code` |

| 5. 클라이언트 → 인증 서버 | `code`와 `client_secret`을 이용해 **access token** 요청 | `grant_type=authorization_code`, `code`, `redirect_uri`, `client_id`, `client_secret` |

| 6. 인증 서버 → 클라이언트 | `access_token`(및 `refresh_token`) 반환 | `access_token`, `refresh_token` |

```
mermaid

sequenceDiagram

    participant User

    participant Client

    participant AuthServer

    User->>Client: 로그인 버튼 클릭

    Client->>AuthServer: Authorization Request (code)

    AuthServer->>User: 로그인·동의 화면

    User->>AuthServer: 인증·동의

    AuthServer->>Client: Redirect with code

    Client->>AuthServer: Token Request (code+secret)

    AuthServer->>Client: Access Token (+Refresh)

```

**특징**

- **보안**: `client_secret`이 서버에만 존재 → 토큰 탈취 위험 낮음.

- **사용처**: 전통적인 웹 애플리케이션, 백엔드 API 서버.

---

## # 2️⃣ PKCE (Proof Key for Code Exchange) – SPA·모바일 전용

PKCE는 **공개 클라이언트**(비밀키를 저장할 수 없는 환경)에서도 Authorization Code Flow를 안전하게 사용하도록 만든 확장입니다.

| 단계 | 설명 | 핵심값 |

|------|------|--------|

| 1. 클라이언트 | `code_verifier`(랜덤 문자열) 생성 → SHA‑256 해시 후 Base64URL 인코딩 → `code_challenge` 생성 | `code_verifier`, `code_challenge` |

| 2. 클라이언트 → 인증 서버 | `code_challenge`와 `code_challenge_method=S256` 포함해 인증 요청 | `code_challenge`, `code_challenge_method` |

| 3. 인증 서버 → 사용자 | 로그인·동의 화면 | – |

| 4. 인증 서버 → 클라이언트 | `code` 반환 (리다이렉트) | `code` |

| 5. 클라이언트 → 인증 서버 | `code`와 **원본** `code_verifier` 전송 | `code_verifier` |

| 6. 인증 서버 | `code_verifier`를 해시해 `code_challenge`와 비교 → 일치하면 토큰 발급 | `access_token` |

```
mermaid

sequenceDiagram

    participant SPA as SPA/모바일

    participant Auth as AuthServer

    SPA->>SPA: generate code_verifier & code_challenge

    SPA->>Auth: Auth Request (code_challenge)

    Auth->>SPA: Redirect with code

    SPA->>Auth: Token Request (code + code_verifier)

    Auth->>SPA: Access Token

```

**장점**

- `client_secret` 없이도 **인증 코드 탈취 방지**.

- SPA, React, Vue, iOS/Android 앱에 최적.

---

## # 3️⃣ Device Code Flow (IoT·스마트 TV 등)

키보드가 없는 디바이스에서도 사용자가 별도 브라우저에서 인증할 수 있게 만든 흐름입니다.

1. **디바이스** → 인증 서버에 `device_code`와 `user_code` 요청.

2. 인증 서버는 **디바이스 코드**, **사용자 코드**, **검증 URL**을 반환.

3. 디바이스는 화면에 **사용자 코드**와 **검증 URL**을 표시.

4. 사용자는 스마트폰·PC에서 URL에 접속해 **user_code** 입력 후 로그인·동의.

5. 디바이스는 일정 간격(`interval`)으로 `device_code`를 사용해 토큰을 **폴링**.

6. 인증이 완료되면 `access_token`을 반환.

```
mermaid

sequenceDiagram

    participant Device

    participant Auth

    participant UserBrowser

    Device->>Auth: POST /device/code

    Auth->>Device: device_code, user_code, verification_uri

    Device->>UserBrowser: Display user_code & URL

    UserBrowser->>Auth: Enter user_code + login

    Auth->>UserBrowser: Consent OK

    loop Polling

        Device->>Auth: POST /token (device_code)

        Auth-->>Device: pending / access_token

    end

```

**활용 사례**

- 스마트 TV, 게임 콘솔, 라즈베리파이 기반 IoT 디바이스.

---

## # 4️⃣ Client Credentials Flow (머신‑투‑머신)

서버 간 API 호출에서 **사용자 개입 없이** 토큰을 발급받는 방식.

1. 클라이언트(서버) → 인증 서버에 `client_id`와 `client_secret` 전송, `grant_type=client_credentials`.

2. 인증 서버는 **즉시** `access_token` 반환.

3. 클라이언트는 토큰을 사용해 리소스 서버에 API 호출.

```
mermaid

sequenceDiagram

    participant ServiceA as Client (Service A)

    participant Auth as AuthServer

    participant API as ResourceServer

    ServiceA->>Auth: Token Request (client_id, client_secret)

    Auth->>ServiceA: Access Token

    ServiceA->>API: API Call (Bearer token)

    API->>ServiceA: Response

```

**특징**

- **사용자** 개입 X → 백엔드 서비스, 배치 작업, CI/CD 파이프라인에 적합.

- **범위(scope)** 를 통해 **허용된 리소스**를 제한한다.

---

# # 🏁 결론 – 오늘 당장 적용해 보세요!

| 흐름 | 언제 쓰나요? |

|------|--------------|

| **Authorization Code** | 전통적인 웹 서버 애플리케이션 |

| **PKCE** | SPA, 모바일 앱(React Native, iOS, Android) |

| **Device Code** | 키보드·마우스 없는 디바이스(스마트 TV, IoT) |

| **Client Credentials** | 서버‑간 통신, 백그라운드 작업 |

> **실전 팁**

> 1. **HTTPS**는 기본 – 모든 토큰 교환은 TLS 위에서만.

> 2. **Refresh Token**을 활용해 장기 세션을 안전하게 유지.

> 3. **Scope**와 **Audience**를 최소 권한 원칙에 맞게 설계.

이제 여러분은 **OAuth 2.0 인증 흐름**을 상황에 맞게 선택하고 구현할 준비가 되었습니다.

🔗 **더 깊이 파고들고 싶다면?**

- 공식 RFC 6749, 7636( PKCE ) 문서

- 각 클라우드 제공자의 SDK 가이드(예: Google, Azure, AWS)

**댓글로 여러분이 실제 적용한 사례를 공유해 주세요!** 여러분의 경험이 다른 초보 개발자에게 큰 도움이 됩니다. 🚀
