OAuth2와 JWT는 현대 웹 애플리케이션에서 인증(Authentication) 과 인가(Authorization) 를 구현할 때 자주 마주치는 핵심 개념입니다. 이 글에서는 두 기술의 역할과 차이점을 명확히 이해하고, 실제 서비스에 어떻게 적용할 수 있는지 살펴보겠습니다.
1. OAuth2 개요
1.1. 개념
OAuth2는 인가 즉, 권한 위임(Authorization) 을 위해 설계된 프로토콜로, 네 가지 역할을 정의합니다.
- Resource Owner(리소스 소유자): 권한을 위임하는 사용자
- Client(클라이언트 애플리케이션): 권한을 위임받아 API에 접근하려는 애플리케이션
- Authorization Server(인가 서버): 토큰 발급 및 검증 담당
- Resource Server(리소스 서버): 보호된 리소스 제공
1.2. OAuth2로 무엇을 할 수 있나?
OAuth2의 목적은 단순히 인증만 처리하는 것이 아니라 사용자의 특정 권한만 제한적으로 위임받는 것입니다. 아래는 OAuth2로 할 수 있는 주요 동작과 그 의미입니다:
동작 | 의미 |
---|---|
로그인 없이 API 호출 | 클라이언트가 access_token을 통해 사용자의 로그인 정보를 직접 다루지 않고도 API 호출 가능 |
권한 범위(scope) 제한 | 사용자의 전체 계정이 아닌, 예: read:user_email , post:comment 등 필요한 리소스만 접근 허용 |
3rd-party 위임 | 예: Github 계정으로 로그인하거나, 카카오톡 친구 목록에 접근 요청 등 다른 서비스의 권한 일부를 안전하게 위임 |
토큰 기반 인증 | 세션 기반 인증 없이 access_token으로 사용자 권한을 관리 가능 |
refresh_token을 통한 무중단 사용자 경험 | access_token 만료 후에도 사용자 재인증 없이 새로운 토큰 발급 가능 |
이러한 기능 덕분에 OAuth2는 모바일 앱, 웹 애플리케이션, 서버 간 통신 모두에서 널리 활용됩니다.
1.3. Authorization Code Grant 흐름 (위임 기반)
-
권한 위임 요청
클라이언트는 사용자를 인가 서버의/authorize
페이지로 리디렉션하여 “내 리소스에 접근해도 괜찮습니까?”를 묻습니다. -
사용자 인증 및 동의
사용자는 인가 서버에서 로그인하고, 클라이언트가 요청한 권한 범위(scope
)에 동의합니다. -
인가 코드 전달
인가 서버는 사용자의 동의 후, 일회용authorization_code
를 클라이언트의 등록된redirect_uri
로 전달합니다.HTTP/1.1 302 Found Location: https://your.app/callback?code=AUTH_CODE&state=xyz123
4. **인가 코드로 토큰 교환**
클라이언트 백엔드는 받은 authorization_code를 인가 서버의 /token 엔드포인트에 자신의 client_id와 client_secret과 함께 전송합니다.
```HTTP
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=https://your.app/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
-
액세스 토큰 발급
인가 서버는 클라이언트의 자격 증명을 검증한 후, access_token과 refresh_token을 발급합니다. -
위임받은 권한으로 리소스 접근
클라이언트는 발급받은 access_token을 HTTP 요청 헤더에 담아 리소스 서버에 요청을 전송합니다.
GET /resource/me
Authorization: Bearer ACCESS_TOKEN
- 토큰 갱신
access_token이 만료되면, 클라이언트는 refresh_token을 /token 엔드포인트에 보내어 새로운 access_token을 발급받습니다.
2. JWT(JSON Web Token) 개요
2.1. 개념
JWT는 토큰 포맷(Token Format) 으로, Claims 기반의 JSON 구조를 가진 자가 포함(self‑contained) 토큰입니다.
- Header: 토큰 타입 및 서명 알고리즘 정보
- Payload: 실제 인증·인가 데이터(Claims)
- Signature: Header와 Payload를 인코딩해 비밀키로 서명
2.2. JWT 구조 예시
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpv
aG4gRG9lIiwiaWF0IjoxNjA5ODQ2ODAwfQ
.
hJtXIZ2uSN5Il_6GghhqTBhJ_gbQSCQjEv5eB6zj4-4
// Header
{
"alg": "HS256",
"typ": "JWT"
}
// Payload (Claims)
{
"sub": "1234567890", // 사용자 ID
"name": "John Doe",
"iat": 1609846800,
"exp": 1609850400
}
3. OAuth2 vs JWT: 비교
구분 | OAuth2 | JWT |
---|---|---|
역할 | 인가(Authorization) 프로토콜 | 토큰 포맷(Token Format)– 자체 포함으로 인증(Authentication)과 인가(Authorization) 모두 표현 가능 |
구성요소 | authorization server, resource server 등 | Header, Payload, Signature |
토큰 형식 | 자유롭게 정의 가능 (Opaque Token 등) | JSON 기반, Base64Url 인코딩된 구조체 |
검증 방식 | 인가 서버 Introspection API 호출 필요 | 서명 검증만으로 자체 검증 가능 |
확장성 | 다양한 Grant Type 지원 (Authorization Code, Client Credentials 등) | Claims에 권한·사용자 정보 등 자유롭게 포함 가능 |
인증 vs 인가 | OAuth2는 인가(Authorization) 에 초점. 별도 Authentication(인증) 시스템 필요 | JWT는 **인증(Authentication)**과 인가(Authorization) 모두 표현 가능 |
단점 | 토큰 검증 시마다 네트워크 호출 필요 | 토큰 탈취 시 만료 전까지 무효화 어려움 |
4. 사용 사례
-
OAuth2 + JWT 조합
- 인가 서버가 JWT를 발급하고, Resource Server는 JWT 서명 검증으로 토큰을 확인
- Introspection API 호출을 최소화하면서도 표준 프로토콜 준수 가능
-
단독 JWT 사용
- 서비스 간 간단한 인증·인가
- 내부 마이크로서비스 호출 토큰으로 활용
5. 장단점 정리
5.1. OAuth2
장점
- 표준화된 권한 위임 프로토콜
- 다양한 클라이언트 유형(웹, 모바일, 서버 간) 지원
주의 사항
- Authorization Code 탈취 방지(State, PKCE)
- HTTPS 적용 필수
- 토큰 저장·만료·회수 정책 설계 필요
5.2. JWT
장점
- 자체 포함형 토큰으로 네트워크 호출 없이 검증 가능
- Claims 확장성 (권한, 사용자 정보 등 포함)
주의 사항
- 토큰 탈취 시 만료 전까지 무효화 어려움
- 비밀키 관리 및 알고리즘 선택 신중
- 토큰 크기 증가 시 네트워크 오버헤드
6. 결론
OAuth2는 표준화된 권한 위임 프로토콜이고, JWT는 자가 포함형 토큰으로 서로의 역할이 다릅니다. 실제 서비스에서는 OAuth2 프로토콜 위에서 JWT를 토큰 형식으로 사용하여, 표준성과 검증 효율성을 동시에 만족시키는 패턴이 널리 쓰입니다. 여러분의 시스템 요구사항에 맞추어 적절한 조합을 선택하고, 보안과 운영 측면을 고려해 설계하시기 바랍니다.
JWT의 경우 최근 프로젝트에 적용할 일이 있어 따로 테스트 프로젝트를 만들어봤습니다. 인증 프로젝트 예제 (NestJS + Next.js)
참고 자료
- RFC 6749: OAuth 2.0
- RFC 7519: JSON Web Token (JWT)