OAuth2 인증 구조 — 쉽게 이해하는 가이드

OAuth2가 뭔지, 구성 요소와 대표 흐름(Authorization Code, Client Credentials 등)을 그림처럼 이해할 수 있게 정리합니다. 실무 팁과 보안 주의사항도 포함.
- OAuth2 = 권한 위임(authorization) 프로토콜. 비밀번호를 전달하지 않고 다른 서비스에 자원 접근 권한 부여.
- 핵심 구성요소: Resource Owner, Client, Authorization Server, Resource Server.
- 대표 흐름: Authorization Code(웹 앱용, 안전), Client Credentials(서버간), Device Code(디바이스), Implicit은 사용 자제.
1. 핵심 구성요소
- Resource Owner — 리소스의 소유자(보통 사용자). 예: your@email.com
- Client — 권한을 요청하는 애플리케이션(웹앱, 모바일앱, 서버 등)
- Authorization Server — 인증 및 토큰 발급 담당(예: Google, Auth0, Keycloak)
- Resource Server — 보호된 리소스(API 서버. 토큰으로 접근 제어)
2. 핵심 개념: 액세스 토큰과 리프레시 토큰
액세스 토큰(Access Token) — Resource Server에 대한 짧은 유효기간의 자격증명. API 호출 시 Authorization 헤더에 담아 보냄.
리프레시 토큰(Refresh Token) — Access Token이 만료되었을 때 Authorization Server에서 새 토큰을 발급받기 위한 토큰(보통 장기 유효). 클라이언트가 안전하게 보관해야 함.
3. 대표 흐름 — Authorization Code (웹 애플리케이션)
1) 클라이언트가 사용자를 Authorization Server의 로그인 페이지로 리다이렉트.
2) 사용자가 로그인하고 동의하면 Authorization Server가 authorization code를 클라이언트의 리다이렉트 URI로 전달.
3) 클라이언트는 이 코드를 Authorization Server에 보내어 access token(및 optional refresh token)을 요청.
4) 받은 액세스 토큰으로 Resource Server API 호출.
토큰 발급이 서버-서버 통신(코드 → 토큰)으로 이뤄져 클라이언트(브라우저)에서 토큰이 노출될 위험이 적음. 서버 사이드 웹앱에 추천.
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://client.example.com/callback
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
4. Client Credentials (서버 간 통신)
사용처 — 백엔드 서비스끼리 인증이 필요할 때 (예: 배치, 마이크로서비스간 API 호출)
흐름 — 클라이언트가 클라이언트 자격증명(client_id/secret)을 Authorization Server로 보내면 바로 액세스 토큰 발급.
POST /oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
5. Device Code (입력 제약 디바이스)
TV, IoT처럼 브라우저 입력이 불편한 환경에서 사용. 디바이스는 사용자에게 제공된 URL과 코드를 표시. 사용자는 다른 기기에서 로그인/동의하면 디바이스가 토큰을 발급받음.
6. 주의: Implicit 흐름은 이제 권장되지 않음
브라우저에서 토큰을 직접 발급해 받는 Implicit 방식은 토큰 노출 위험 때문에 최신 권고(OAuth2.1)에서는 권장하지 않습니다. 대신 Authorization Code + PKCE 사용 권장.
7. PKCE (Proof Key for Code Exchange) — 모바일/SPA에서 필수
핵심 — Authorization Code 흐름에 추가되는 안전장치. 클라이언트가 임의의 코드 챌린지를 만들어 전달하고, 토큰 교환 시 원본 코드 베리파이를 제공해야 토큰 발급.
공개 클라이언트(비밀을 안전하게 보관할 수 없는 클라이언트, 예: 모바일 앱, SPA)에 필수적으로 사용.
8. 실무 팁 & 보안 체크리스트
- 가능하면 Authorization Code + PKCE 사용.
- Implicit 흐름은 사용하지 마세요.
- 리프레시 토큰은 클라이언트에 안전하게 저장(브라우저 저장소에 저장 금지).
- HTTPS 필수 — 토큰은 평문 전송 금지.
- 토큰의 권한(scope)을 최소 권한 원칙으로 설정.
- 토큰 만료와 리프레시 전략을 설계(짧은 수명 + 재발급 권장).
- 클라이언트 시크릿은 서버 사이드에서만 보관 — 공개 클라이언트는 시크릿을 가질 수 없음.
- 로그인/동의 화면에서 요청하는 권한을 사용자에게 명확히 보여주기.
9. 전체 시퀀스(텍스트 다이어그램)
[사용자] → (브라우저) → [클라이언트] → (redirect to) → [Authorization Server: 로그인/동의]
[Authorization Server] → (redirect back with code) → [클라이언트 서버]
[클라이언트 서버] → (POST code) → [Authorization Server] → (returns access_token, refresh_token)
[클라이언트 서버] → (API call with Bearer access_token) → [Resource Server]
마무리
OAuth2는 처음엔 복잡해 보이지만, 핵심은 '사용자 비밀번호를 직접 건네지 않고 대신 토큰으로 권한을 위임'한다는 점입니다. 흐름별 용도와 보안 권고(PKCE, HTTPS, 최소 권한)를 지키면 안전한 인증 구성이 가능합니다.
'개발 · IT > 보안 · 시큐어 코딩' 카테고리의 다른 글
| CSRF 공격이란? 원리부터 방어 방법까지 정리 (0) | 2025.12.22 |
|---|---|
| 쿠팡 사태를 보며 — 시큐어코딩을 하는 개발자가 느낀 점 (0) | 2025.12.04 |
| XSS 방어 코드 — 쉽게 적용하는 방법 (0) | 2025.12.04 |
| 🔒 Nginx Proxy Manager에서 특정 IP만 허용하는 방법 (0) | 2025.11.27 |
| Burp Suite로 HTTP/HTTPS 요청·응답 가로채기 — 실무 가이드 (0) | 2025.11.27 |
댓글