"Google로 로그인", "GitHub으로 로그인" 버튼을 본 적이 있을 것이다. 이 기능의 핵심이 바로 OAuth 2.0이다.
사용자 입장에서는 편리하고, 개발자 입장에서는 비밀번호를 직접 다루지 않아도 된다. 그렇다면 OAuth 2.0은 정확히 어떻게 동작하는 것일까?
OAuth 2.0이란?
OAuth 2.0은 제3자 애플리케이션이 사용자의 리소스에 안전하게 접근할 수 있도록 하는 인가(Authorization) 프로토콜이다.
핵심은 비밀번호를 공유하지 않는 것이다. 사용자는 Google 비밀번호를 제3자 앱에 알려주지 않으면서도, 해당 앱이 Google 프로필 정보에 접근하도록 허용할 수 있다.
주요 역할 (Roles)
OAuth 2.0에는 세 가지 핵심 역할이 있다.
Resource Owner (리소스 소유자)
보호된 리소스의 실제 소유자이다. 일반적으로 사용자를 의미하며, 자신의 데이터에 대한 접근 권한을 부여할 수 있는 주체이다.
Client (클라이언트)
사용자의 리소스에 접근하려는 제3자 애플리케이션이다. Resource Owner를 대신하여 리소스에 접근한다.
Resource Server (리소스 서버)
보호된 리소스를 호스팅하는 서버이다. Access Token을 검증하고 리소스를 제공한다.
실제로는 Authorization Server(인가 서버)와 Resource Server가 분리되어 있지만, 설명의 편의를 위해 하나로 표현한다.
Client 등록
OAuth 2.0을 사용하기 전에, Client는 먼저 Resource Server에 자신을 등록해야 한다.
등록 과정
Client가 Resource Server에 등록하면, 다음 정보들이 설정된다.
| 항목 | 설명 |
|---|---|
| Client ID | 클라이언트를 식별하는 공개 식별자 |
| Client Secret | 클라이언트 인증에 사용되는 비밀 키 (절대 공개 금지) |
| Redirect URI | 인가 코드를 받을 콜백 URL |
등록 완료 후 상태
등록이 완료되면 Client와 Resource Server 모두 동일한 Client ID와 Client Secret을 공유하게 된다.
Authorization Code Flow
OAuth 2.0의 가장 일반적인 인가 방식인 Authorization Code Grant 흐름을 단계별로 살펴본다.
Step 1: 인가 요청 (Authorization Request)
Client가 Resource Owner를 Resource Server의 인가 엔드포인트로 리다이렉트한다.
https://resource.server/
?client_id=1
&scope=B,C
&redirect_uri=https://client/callback
파라미터 설명:
client_id: 등록된 Client의 식별자scope: 요청하는 권한 범위 (예: 프로필 읽기, 이메일 읽기)redirect_uri: 인가 코드를 받을 콜백 URL
Resource Owner는 Resource Server의 로그인 페이지에서 인증하고, 요청된 scope에 대한 접근을 승인한다.
Step 2: Authorization Code 발급
Resource Owner가 승인하면, Resource Server는 Authorization Code를 생성하고 Client의 redirect_uri로 리다이렉트한다.
Location: https://client/callback?code=3
이 코드는 일회용이며, 짧은 유효 기간을 가진다.
Step 3: Authorization Code 수신
Resource Owner의 브라우저가 redirect_uri로 이동하면서 Authorization Code가 Client에게 전달된다.
Step 4: Access Token 요청
Client는 받은 Authorization Code를 사용하여 Resource Server에 Access Token을 요청한다.
https://resource.server/token?
grant_type=authorization_code&
code=3&
redirect_uri=https://client/callback&
client_id=1&
client_secret=2
이 요청에는 client_secret이 포함된다. 이 단계는 서버 간 통신으로 이루어지므로 secret이 브라우저에 노출되지 않는다.
Step 5: Access Token 발급
Resource Server는 요청을 검증하고 Access Token을 발급한다.
Access Token이 발급되면 Client와 Resource Server 모두 이 토큰을 공유하게 된다. 이제 Client는 이 토큰으로 Resource Owner의 리소스에 접근할 수 있다.
Access Token 사용
Client는 Access Token을 사용하여 Resource Server의 API를 호출한다.
일반적으로 Access Token은 HTTP Authorization 헤더에 포함되어 전송된다.
Authorization: Bearer {access_token}
Resource Server는 토큰을 검증하고, 유효하면 요청된 리소스를 반환한다.
Refresh Token
Access Token은 보안을 위해 짧은 유효 기간을 가진다. 토큰이 만료될 때마다 사용자가 다시 인가 과정을 거쳐야 한다면 매우 불편할 것이다.
이 문제를 해결하는 것이 Refresh Token이다.
Refresh Token Flow
- (A) Client가 Authorization Grant를 Authorization Server에 전송
- (B) Authorization Server가 Access Token과 Refresh Token을 발급
- (C) Client가 Access Token으로 리소스 요청
- (D) Resource Server가 보호된 리소스 반환
- (E) Client가 (만료된) Access Token으로 다시 요청
- (F) Resource Server가 Invalid Token Error 반환
- (G) Client가 Refresh Token으로 새 토큰 요청
- (H) Authorization Server가 새 Access Token (및 선택적으로 새 Refresh Token) 발급
Access Token vs Refresh Token
| 특성 | Access Token | Refresh Token |
|---|---|---|
| 용도 | 리소스 접근 | Access Token 갱신 |
| 유효 기간 | 짧음 (분~시간) | 김 (일~월) |
| 전송 대상 | Resource Server | Authorization Server |
| 노출 위험 | 상대적으로 높음 | 낮음 (서버 간 통신) |
보안 고려사항
OAuth 2.0을 구현할 때 반드시 지켜야 할 보안 원칙들이다.
- HTTPS 필수: 모든 OAuth 2.0 통신은 HTTPS를 통해 이루어져야 한다.
- State 파라미터: CSRF 공격 방지를 위해 state 파라미터 사용이 권장된다.
- Client Secret 보호: Client Secret은 절대 클라이언트 사이드 코드에 노출되면 안 된다.
- Redirect URI 검증: 등록된 redirect_uri만 허용하여 Authorization Code 탈취를 방지한다.
- Scope 최소화: 필요한 최소한의 권한만 요청해야 한다.
정리
OAuth 2.0의 핵심 개념을 정리하면 다음과 같다.
| 구성 요소 | 설명 |
|---|---|
| Roles | Resource Owner, Client, Resource Server (+ Authorization Server) |
| Client Registration | Client ID, Client Secret, Redirect URI |
| Authorization Code Flow | 가장 안전한 인가 방식 |
| Tokens | Access Token (리소스 접근), Refresh Token (토큰 갱신) |
OAuth 2.0을 통해 사용자는 비밀번호를 공유하지 않으면서도 제3자 애플리케이션에 제한된 접근 권한을 안전하게 부여할 수 있다.
HGU 전산전자공학부 고윤민 교수님의 24-2 컴퓨터 보안 수업을 듣고 작성한 포스트이며, 첨부한 모든 사진은 교수님 수업 PPT의 사진 원본에 필기를 한 수정본입니다.