개요
최근 소셜 로그인 (Google, Github, Kakao, Line 등)을 구현하거나, 사용자 계정 연결 기능을 만들어 본 개발자라면 OIDC(OpenID Connect)라는 개념을 마주치게 됩니다. 저 또한 최근 계정 연결 기능을 구현하면서 OIDC에 대해 알게되었습니다.
이 포스팅에서는 OIDC가 정확히 무엇인지, OAuth 2.0과는 어떻게 다른지, 그리고 실무에서 왜 중요한지를 차근차근 정리해보겠습니다.
1. OAuth 2.0의 한계 - "인증"과 "인가"의 혼동
OAuth 2.0은 현재 많은 곳에서 사용되는 표준 프로토콜이지만, 원래의 설계 목적을 이해하는 것이 중요합니다.
OAuth 2.0의 원래 목적: 인가 (Authorization)
OAuth 2.0은 "인가" 프로토콜입니다. 즉 "사용자가 자신의 리소스에 제3자 애플리케이션이 접근할 수 있도록 허가하는 것"이 목적입니다.
실제 사례
- 사용자가 Instagram 앱에서 "Fackbook 계정으로 로그인"을 선택
- Instagram이 Facebook의 사진, 친구 목록 등에 접근할 수 있는 권한을 얻는 것
이것이 OAuth 2.0의 핵심입니다.
문제: 사용자의 "신원"을 확인할 수 없다
그런데 여기서 문제가 발생합니다. OAuth 2.0은 사용자의 신원(Identity)을 확인하는 것이 아니라, 단순히 "누군가 이 권한을 승인했다"는 것만 증명하는 것입니다.
문제상황
- 해커가 OAuth 서버에서 Access Token을 탈취함
- 해커는 탈취한 토큰을 사용하여 API를 호출
- API 서버 입장에서는 "누가 이 요청을 했는지" 알 수 없음
- 즉, Access Token만 있으면 누구든 API(리소스)를 사용할 수 있음
따라서 OAuth 2.0 만으로는 "이 사용자가 정말 John Smith인지"를 확인할 수 없습니다.
2. OIDC(OpenID Connect)란 무엇인가?
OIDC는 OAuth 2.0위에 인증계층(Identity Layer)을 추가한 것입니다.

OIDC의 핵심: ID Token
OIDC는 OAuth 2.0의 Access Token에 추가로 ID Token을 제공합니다.
ID Token은 JWT (Json Web Token) 형식이며, 다음과 같은 사용자 정보를 포함합니다.
- sub (Subject): 사용자의 고유 ID
- email: 사용자의 email
- name: 사용자 이름
- picture: 사용자 프로필 사진
- aud (Audience): 이 토큰이 어떤 애플리케이션을 위한 것인지 (토큰 발급 대상)
- iss (Issuer): 토큰을 발급한 주체 (예: https://accounts.google.com)
- exp (Expiration): 토큰 만료 시간
ID Token으로 사용자 확인
ID Token은 디지털 서명(Digital SIgnature)이 되어있기 때문에 위변조를 확인할 수 있습니다.
따라서 서버는
- ID Token의 서명을 검증합니다.
- 서명이 유효하면 "이것은 확실히 Google이 발급한 토큰입니다." 라고 확신합니다.
- 토큰에 담긴 사용자 정보를 신뢰하고 사용합니다.
3. ID Token vs Access Token 핵심 차이
OIDC를 이해하려면 두 토큰의 차이를 명확히 해야 합니다.
Access Token
- 목적: 리소스에 접근하기 위한 허가증
- 사용처: API 서버에 요청할 때 사용
- 내용: 일반적으로 불투명한 문자열 (서버만 해석 가능)
AccessToken 예시
Authorization: Bearer ya29.a0AfH6SMBx... (HTTP 헤더로 전송하는 경우)
Access Token을 사용해서 다음과 같은 것들을 할 수 있습니다.
- 구글의 Gmail API 호출
- 구글의 Calendar API 호출
- 사용자의 구글 드라이브 파일 접근 등
ID Token
- 목적: 사용자의 신원 확인
- 사용처: 로그인할 때 사용 (API 접근 X)
- 내용: JWT 형식으로 사용자 정보 포함
ID Token 예시
eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZW1haWwiOiJqb2huQGV4YW1wbGUuY29tIiwiaWF0IjoxNjM0MjM0NTY3LCJleHAiOjE2MzQyMzgxNjd9.signature
JWT Header
{
"alg": "RS256",
"kid": "1"
}
JWT Payload
{
"sub": "1234567890",
"name": "John Doe",
"email": "john@example.com",
"iat": 1634234567,
"exp": 1634238167
}
ID Token의 특징을 정리해보면 다음과 같은 것들이 있습니다.
- JWT이기 때문에 내용을 직접 볼 수 있습니다. (Base64 디코딩)
- 디지털 서명이 되어있기 때문에 위변조 탐지 가능.
- 로그인 목적으로만 사용됨(API 호출에 사용하면 안됨)
- 일반적으로 짧은 만료 시간(예: 1시간)
비유: 회원권 vs 신분증
AccessToken은 회원권에, ID Token은 신분증에 비유를 해볼 수 있습니다.
- AccessToken: 헬스장 회원권 (당신이 시설을 이용할 권리가 있는지 확인)
- ID Token: 신분증 (당신이 정말 John Doe인지 확인)
4. ID Token의 구조 - JWT 형식
앞서 설명드렸듯이, ID Token은 JWT(Json Web Token)으로 인코딩되어 있습니다. 크게 세 부분으로 나누어 볼 수 있습니다.
JWT의 구조 : Header.Payload.Signature
eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.
eyJzdWIiOiIxMjM0NTY3ODkwIiwiZW1haWwiOiJqb2huQGV4YW1wbGUuY29tIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjM0MjM0NTY3LCJleHAiOjE2MzQyMzgxNjd9.
TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
1) Header
JWT의 서명에 사용된 알고리즘과 키 ID, 토큰 타입등의 정보를 담고 있습니다.
{
"alg": "RS256", // 사용된 서명 알고리즘
"kid": "1" // 서명 키의 ID
}
2) Payload
OIDC의 실제 데이터 (클레임)를 담는 부분입니다.
{
"sub": "1234567890", // 사용자 고유 ID
"email": "john@example.com", // 이메일
"name": "John Doe", // 이름
"picture": "https://...", // 프로필 사진 URL
"aud": "YOUR_CLIENT_ID", // 이 토큰의 수신자 (당신의 앱)
"iss": "https://accounts.google.com", // 발급자
"iat": 1634234567, // 발급 시간 (Unix timestamp)
"exp": 1634238167 // 만료 시간 (Unix timestamp)
}
3) Signature (서명)
헤더와 페이로드를 합친 문자열을 비밀키(Secret Key)로 서명한 값으로, 공개키(Public Key)를 사용해 검증할 수 있습니다.
5. Google OIDC 플로우
여러 OIDC 중 실제 구글 OIDC 플로우가 어떻게 동작하는지 간단하게 살펴보겠습니다.
1) 인증 요청
- 클라이언트 앱이 사용자의 브라우저를 구글의 인증 엔드포인트(https://google.com)로 리디렉션 합니다.
- 이때 response_type=code, scope=openid email profile 등의 파라미터를 함께 전달합니다.
2) 사용자 로그인 및 동의 (Login & Consent)
- 사용자가 구글 계정에 로그인하고 앱이 요청하는 권한(범위)에 동의합니다.
3) 인증코드 발급 (Authorization Code) 발급
- 구글 서버가 사용자의 브라우저를 사전에 등록된 redirect_uri 로 돌려보내면서 일회용 인증코드를 전달합니다.
4) 토큰 교환 (Token Exchange)
- 클라이언트 백엔드가 구글 토큰 엔드포인트(https://googleapis.com)로 POST 요청을 보내어 인증 코드를 Access Token 및 ID Token(JWT)과 교환합니다.
5) 사용자 정보 확인 (ID Token Validation)
- 클라이언트는 구글의 서명한 ID Token을 검증하여 사용자의 고유 식별자(sub), 이메일, 프로필 정보 등을 안전하게 획득하고 로그인 처리를 완료합니다.
6. OIDC vs OAuth 2.0 비교
| 항목 | OAuth 2.0 | OIDC |
| 목적 | 인가 (Authorization) | 인증 + 인가 (Authentication + Authorization) |
| 사용자 신원 확인 | X, 불가능 | O, 가능 |
| 반환 토큰 | Access Token | ID Token + Access Token |
| 토큰 포맷 | 불투명한 문자열 | JWT(검증 가능) |
| 사용 사례 | API 접근 권한 | 소셜 로그인 |
| 발급 기관 | 구글, Github등 | 구글, Github등 (OIDC Provider) |
| 토큰 내용 확인 | X | O (서명 검증 후) |
| 사용자 정보 | 별도 API 호출 필요 | 토큰에 포함됨 |
언제 어떤걸 사용할까?
OAuth 2.0만 필요한 경우
- 사용자의 Google Drive 파일에 접근하고 싶을 때
- 구글 Calendar를 읽고 싶을 때
- 단순히 "권한"이 필요한 경우
OIDC가 필요한 경우
- 소셜 로그인 구현 (Google 계정으로 로그인 등)
- 사용자의 신원을 확인해야 할 때
- 사용자 정보(이메일, 이름 등)를 안전하게 받고 싶을 때
7. 실무 사례
구글의 OIDC를 사용한 실무 사례를 하나 소개하겠습니다.
다음과 같은 요구사항이 있었습니다.
- 사용자가 이미 특정 이메일(여기서는 gmail로 가정)로 회원 가입되어 있으며, 이메일과 패스워드를 사용하여 로그인 할 수 있음
- 같은 사용자가 패스워드 로그인이 아닌 "Google 계정으로 로그인" 기능을 통해 로그인 시도
- Google 계정의 이메일이 기존에 가입된 이메일과 같으면, 두 로그인 방식이 같은 계정으로 연결되어야 한다.
이 요구사항을 구현하기 위해 OIDC 의 ID Token을 활용했습니다.
- 위의 Google OIDC 플로우에서 설명했던 것 처럼, 구글 인증 후 ID Token 정보를 획득할 수 있습니다.
- 이 때 우리는 사용자의 이메일 정보가 필요하므로 scope=openid email 파라미터를 전달하여 ID Token에 email이 포함될 수 있도록 합니다.
- ID Token으로부터 email 정보를 추출한 뒤, 해당 email 이 이미 가입되어있는 계정인지 확인합니다.
- 만약 계정이 존재한다면, 해당 계정이 지금 로그인한 구글 계정의 소유자와 동일하다는 정보를 저장합니다. (ID Token의 sub 클레임을 저장)
8. 요약
주요 개념들을 정리하고 마무리 하겠습니다.
| 개념 | 설명 |
| OAuth 2.0 | 사용자가 제3자에게 권한을 위임하는 프로토콜. "인가"에 특화됨. |
| OIDC (Open ID Connect) | OAuth 2.0에 "인증 계층"을 추가, ID Token 이라는 JWT 가 추가됨. |
| ID Token | 사용자 신원을 증명하는 JWT. 디지털 서명으로 검증 가능. |
| Access Token | API 접근 권한을 나타대는 토큰. 개인 정보 접근 시 사용. |
| 핵심 차이점 | OIDC는 "당신이 누구인지" 확인. - Who you are OAuth 2.0은 "당신이 무엇을 할 수 있는지" 확인. - What can you do |