548. OpenID Connect (OIDC) - OAuth 2.0 기반 사용자 인증(Authentication) 프로토콜
핵심 인사이트 (3줄 요약)
- 본질: OpenID Connect (OIDC)는 '권한(인가)' 위임에만 특화되어 있던 기존 OAuth 2.0 프로토콜 위에, 사용자의 '신원(인증)' 정보를 전달하는 ID Token(JWT 포맷) 구조를 얹어 완성한 현대적 분산 인증 표준이다.
- 가치: 수많은 스타트업과 모바일 앱이 자체 로그인 시스템을 만들고 비밀번호를 관리해야 하는 짐을 벗어던지고, 구글·카카오·애플 등의 거대 플랫폼의 신뢰 자산을 빌려 쓰는 소셜 로그인 (Social Login) 아키텍처를 전 세계에 표준화시켰다.
- 융합: OIDC는 OAuth 2.0의 Access Token 흐름에 완전히 기생하여 융합되므로, 개발자는 OAuth의 인프라(보안 채널, 리다이렉트)를 그대로 재사용하면서도 JWT라는 최신 웹 표준을 통해 무거운 SAML(XML)을 완벽히 대체하는 극강의 가벼움(Lightweight)을 달성했다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
- 개념: OpenID Connect는 비영리 재단인 OpenID Foundation에서 제정한 자격 증명(Identity) 레이어다. OAuth 2.0 프로토콜을 뼈대로 삼아, 클라이언트(앱)가 인가 서버(IdP)에게 "이 토큰을 발급받은 사용자가 구체적으로 누구(이름, 이메일, 프로필 사진)인지"를 검증할 수 있게 해주는 표준화된 규격이다.
- 필요성: OAuth 2.0(546번 문서)은 "이 앱이 내 캘린더에 글을 쓰게 해줘"라는 **권한(인가)**을 넘겨주는 Access Token만 발급한다. 이 토큰은 뜻을 알 수 없는 난수 문자열이라, 앱 개발자가 이 토큰을 들고 온 사용자가 홍길동인지 이순신인지, 심지어 언제 로그인했는지 알 방법이 없었다. 그래서 개발자들은 억지로 OAuth로 발급받은 권한 토큰을 가지고 다시 페이스북 API 서버를 찔러 유저 정보를 가져와서 로그인 처리(Authentication)를 하는 등 기형적인 해킹(Confused Deputy 문제)을 일삼았다. "그냥 처음부터 토큰 안에 명함(신원)을 파서 같이 주면 안 되나?"라는 절실한 요구가 OIDC의 탄생 배경이다.
- 등장 배경: ① 초기 OpenID 1.0/2.0의 복잡성과 OAuth와의 파편화 → ② OAuth 2.0 남용에 따른 심각한 보안/인증 사고 빈발 → ③ OAuth 2.0 아키텍처 위에 JWT (JSON Web Token) 포맷의 신분증을 한 장 더 끼워 넣은 깔끔한 통합 표준(OIDC) 제정.
┌─────────────────────────────────────────────────────────────┐
│ OAuth 2.0 한계와 OpenID Connect(OIDC)의 해결책 시각화 │
├─────────────────────────────────────────────────────────────┤
│ │
│ [과거: OAuth 2.0 오용 사태 - 반쪽짜리 인증] │
│ 앱: "구글아 토큰 줘!" ─▶ 구글: "여기 [Access Token: 8fx#@...]" │
│ 앱: "근데 이 토큰 주인이 누구야? 이름이 뭐야? 알 수 없네..." │
│ (결과: 앱이 유저 신원을 몰라 자사 DB에 로그인을 못 시킴. 억지 연동) │
│ │
│ [현재: OIDC의 완벽한 인증 (소셜 로그인)] │
│ 앱: "구글아 OIDC 스코프(openid)로 토큰 줘!" │
│ 구글: "여기 [Access Token: 8fx#@... (이건 캘린더용)] 이랑, │
│ [ID Token: eyJhbG... (이건 유저 신분증 명찰)] 같이 받아!" │
│ │
│ 앱: "앗, ID Token을 열어보니 이름: 홍길동, 메일: hong@gmail 이네! │
│ 로그인 처리 완료!" │
└─────────────────────────────────────────────────────────────┘
[다이어그램 해설] 이 도식은 IT 업계에서 가장 흔하게 혼동하는 OAuth와 OIDC의 차이를 1초 만에 박살 내준다. OAuth는 목적지 서버의 문을 따기 위한 '열쇠(Access Token)'만 준다. 열쇠에는 주인의 이름이 안 적혀 있다. OIDC는 앱(클라이언트)을 호출할 때 스코프(Scope)에 openid라는 단어를 추가로 넣기만 하면, 인가 서버(구글)가 열쇠와 함께 '얼굴 사진과 이름이 박힌 사원증(ID Token)'을 세트로 던져준다. 앱은 그 사원증을 보고 바로 자사 DB의 회원과 매칭시켜 완벽한 '구글로 로그인' 기능을 구현할 수 있게 된다.
- 📢 섹션 요약 비유: OAuth가 영화관에 들어갈 수 있는 '티켓(입장 권한)'이라면, OIDC는 그 티켓을 예매한 사람의 얼굴과 나이가 적힌 '주민등록증(신원 증명)'을 티켓에 스테이플러로 함께 찍어주는 것입니다. 이제 영화관 직원은 이 사람이 누군지 정확히 알고 성인 영화인지 판단할 수 있습니다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
구성 요소 (OIDC 4대 핵심)
| 요소명 | 의미 및 역할 | 작동 원리 | 비유 |
|---|---|---|---|
| OIDC Provider (OP) | 인증 제공자 | 사용자를 인증하고 클라이언트에게 ID Token을 발급하는 거대 플랫폼 서버 (구글, 카카오) | 국가 신분증 발급처 |
| Relying Party (RP) | 클라이언트 (앱) | OP를 믿고(Rely) 사용자의 신원 정보를 넘겨받아 로그인 처리를 하는 타사 앱 | 신분증 검사하는 술집 |
| ID Token | 디지털 신분증 | 사용자의 신원, 토큰 발급 시간, 만료 시간 등을 서명하여 담은 JWT (JSON Web Token) 포맷의 덩어리 | 주민등록증 본체 |
| UserInfo Endpoint | 추가 정보 조회소 | ID Token에 다 담지 못한 주소, 전화번호 등의 추가 프로필을 Access Token을 내밀고 더 가져올 수 있는 API 주소 | 주민센터 무인 발급기 |
OIDC (ID Token) 통신 흐름도 (Authorization Code Flow 결합)
OIDC는 OAuth 2.0의 흐름(Dance)에 거의 100% 무임승차한다. 개발자가 서버로 보내는 파라미터 중에 scope=openid 딱 하나만 더 추가하면, 마지막 응답 단계에서 기적이 일어난다.
┌───────────────────────────────────────────────────────────────┐
│ OIDC 소셜 로그인 인증 흐름 (OAuth 2.0 기반) │
├───────────────────────────────────────────────────────────────┤
│ │
│ [사용자(Browser)] [RP (우리가 만든 앱)] [OP (카카오/구글)]│
│ │ │ │ │
│ │ ① "카카오로 로그인" 클릭 │ │ │
│ ├────────────────────────────▶│ │ │
│ │ │ ② Redirect (scope=openid) │
│ │ ③ 카카오 로그인 화면으로 이동 │◀──────────────────────┤ │
│ │◀────────────────────────────┤ │ │
│ │ │ │ │
│ │ ④ 카카오 계정 로그인 & 정보 제공 동의 │ │
│ ├────────────────────────────────────────────────────▶│ │
│ │ │ │
│ │ ⑤ 임시 "Auth Code" 발급 후 RP 앱으로 Redirect │ │
│ │◀────────────────────────────────────────────────────┤ │
│ │ │ │ │
│ │ ⑥ Code를 우리 앱(백엔드)으로 전달│ │ │
│ ├────────────────────────────▶│ │ │
│ │ │ ⑦ Code + Secret 제시 │ │
│ │ ├──────────────────────▶│ │
│ │ │ │ │
│ ==== 여기서부터 OIDC의 마법이 발동 (Access Token과 ID Token 동시 발급) ==== │
│ │ │ │ │
│ │ │ ⑧ [Access Token] + │ │
│ │ │ [ID Token (JWT)] 반환│ │
│ │ │◀──────────────────────┤ │
│ │ │ │ │
│ │ ⑨ ID Token 뜯어보고(Decoded) "홍길동" 자동 회원가입 및 로그인 처리! │
└───────────────────────────────────────────────────────────────┘
[다이어그램 해설] 앞서 546번 문서에서 본 OAuth 2.0 흐름과 ⑦번까지 완벽히 똑같다. 하지만 ⑧번 응답을 받을 때, 백엔드 앱(RP)은 목적지 서버를 열 수 있는 열쇠인 Access Token뿐만 아니라, 클라이언트 본인이 뜯어서 읽어볼 수 있는 명찰인 ID Token을 덤으로 받는다. 이 ID Token은 JSON 형식으로 만들어져 있어(JWT), RP 서버는 추가로 카카오 API 서버를 찌를 필요 없이 토큰만 뜯어서 이메일과 닉네임을 알아내고 즉시 로그인 완료 화면을 띄울 수 있다. 엄청난 속도 향상과 로직의 단순화를 가져온다.
- 📢 섹션 요약 비유: 피자(Access Token)를 시켰는데 콜라(ID Token)가 세트로 같이 배달 온 것과 같습니다. 예전에는 피자만 와서 콜라를 마시려면 다시 가게에 전화해서 주문(추가 API 호출)해야 했지만, 이제는 한 번 배달에 둘 다 오니 바로 맛있게 먹고 로그인 처리를 끝낼 수 있습니다.
Ⅲ. 융합 비교 및 다각도 분석
ID Token의 내부 구조 (Claims) 및 검증 메커니즘
OIDC가 발급하는 ID Token은 JWT (JSON Web Token)라는 표준 포맷(549번 문서에서 상술)을 따른다. 그 안에는 사용자의 정보를 나타내는 **클레임(Claims)**이라는 속성 조각들이 들어 있다.
| 주요 클레임 (Claims) | 의미 | 설명 (예시) |
|---|---|---|
| iss (Issuer) | 발급자 | 이 신분증을 누가 발급했는가? (예: https://accounts.google.com) |
| sub (Subject) | 주체 식별자 | 구글 세계에서 이 사람의 절대 바뀌지 않는 고유 번호 (예: 107691503...) |
| aud (Audience) | 관객 (수신자) | 이 신분증을 받을 자격이 있는 자 (내 앱의 Client ID와 일치해야 함) |
| exp (Expiration) | 만료 시간 | 이 신분증의 유효기간 (보통 발급 후 10분 등 극히 짧게 세팅) |
| iat (Issued At) | 발급 시간 | 이 신분증이 언제 만들어졌는가? (타임스탬프) |
┌───────────────────────────────────────────────────────────────┐
│ ID Token (JWT) 탈취에 대비한 강력한 서명 검증 원리 │
├───────────────────────────────────────────────────────────────┤
│ │
│ [해커의 장난 시도] │
│ 해커가 ID Token 중간의 "sub":"홍길동" 을 "sub":"관리자" 로 조작함. │
│ │
│ [우리 앱 (RP)의 방어 로직] │
│ RP: "어? 구글이 준 토큰이네. 근데 구글 진짜 도장(서명)이 찍혀있나?" │
│ │
│ 1. 구글의 공개키(Public Key) 서버에 접속해 구글의 자물쇠를 가져옴. │
│ 2. 해커가 바꾼 조작된 문서(Payload)와 구글 자물쇠를 수학적으로 맞춰봄 (RSA).│
│ 3. RP: "이봐! 문서 내용이 바뀌어서 구글 도장(Signature)이랑 수학 공식이 안 맞아!"│
│ │
│ => 결과: 해커의 위조 로그인 시도 100% 차단 (인증 거부 Drop) │
└───────────────────────────────────────────────────────────────┘
[다이어그램 해설] OIDC가 단순한 JSON 덩어리가 아니라 위대한 보안 규격인 이유는 끝부분에 달린 디지털 서명(Signature) 덕분이다. 카카오나 구글(OP)은 ID 토큰을 만들 때 자신들의 절대 비밀인 '개인키(Private Key)'로 문서 전체를 암호학적으로 도장 찍어 보낸다. 우리 앱(RP)은 토큰 안의 이메일이나 이름(Payload)을 믿기 전에, 반드시 구글의 '공개키(Public Key)'를 가져와서 그 도장이 진짜 구글이 찍은 게 맞는지 역산해본다. 단 한 글자라도 위조되었다면 서명 공식이 깨져서 즉각 튕겨낸다. 이 서명 검증을 빼먹는 것이 초보 개발자들이 가장 많이 저지르는 최악의 보안 결함이다.
- 📢 섹션 요약 비유: 신분증 종이에 누군가 볼펜으로 이름에 줄을 긋고 '대통령'이라고 고쳐 써 놨더라도, 종이 밑에 찍힌 경찰청 홀로그램 스티커(디지털 서명)가 훼손된 것을 특수 손전등(공개키 검증)으로 비춰보고 "이건 위조 신분증이다!"라며 입구 컷을 하는 과학 수사 기법입니다.
Ⅳ. 실무 적용 및 기술사적 판단
실무 시나리오: 토스(Toss), 뱅크샐러드 등 마이데이터 생태계에서의 OIDC 활용
- 상황: 고객이 핀테크 앱(토스)에 가입하면서, 국민은행에 있는 자신의 계좌 정보를 끌어오고 싶다. 핀테크 앱은 고객이 진짜 그 고객이 맞는지(인증)와 계좌 열람 권한(인가)을 동시에 얻어내야 한다.
- 과거의 한계: 구형 OAuth만 쓰면 권한은 받지만, 이 고객이 토스 앱의 회원가입자 정보와 완벽히 일치하는지 국민은행 측에서 강력하게 확인해 주지 못해 대포통장 연동 등의 사기 위험이 컸다.
- 의사결정 및 OIDC 조치 (FAPI 표준 결합):
- 금융권 마이데이터 규격(FAPI)은 **OAuth 2.0 인가(계좌 열람)와 OIDC 인증(고객 본인 확인)**을 하나의 세트로 묶어 강제한다.
- 고객이 토스에서 "국민은행 연동"을 누르면 국민은행(OP) 인증 창이 뜬다.
- 국민은행은 로그인한 고객이 맞는지 확인 후, 토스 앱(RP)에게
Access Token(계좌 열람 열쇠)과ID Token(이 사람은 주민번호 뒷자리 XX인 홍길동이 맞음)을 세트로 넘겨준다. - 토스 앱 백엔드는 ID 토큰의 서명을 완벽히 검증하여 "진짜 국민은행이 보증한 홍길동이 맞네"라고 신원을 100% 확정한 뒤, Access Token으로 계좌를 조회해 대시보드에 뿌려준다.
도입 체크리스트 및 안티패턴
-
aud(Audience) 및 nonce 검증 누락 금지: ID 토큰을 받을 때 개발자가 라이브러리를 대충 쓰면 서명만 확인하고 끝내는 경우가 많다. 해커가 다른 앱(예: 해커의 게임 앱)에서 탈취한 구글 ID 토큰을 우리 앱의 로그인 창에 슬쩍 밀어 넣는 공격(Token Substitution)이 발생할 수 있다. 토큰을 뜯었을 때
aud(관객)필드에 적힌 Client ID가 반드시 우리 회사가 구글에서 발급받은 ID와 일치하는지 확인해야 하며, CSRF 방어를 위해nonce(일회용 난수) 값의 일치 여부를 무조건 검증해야 한다. -
안티패턴: 발급받은 OIDC의 ID Token 자체를 우리 앱 서비스의 세션(Session) 유지용 토큰으로 재사용하는 행위. 구글이 발급해 준 ID Token은 "구글이 이 사람을 인증했음"을 증명하는 1회성 명함일 뿐이다. 이걸 쿠키에 구워 넣고 계속 API 인증에 쓴다면, 구글 쪽에서 계정이 정지되어도 우리 앱에서는 토큰 만료 전까지 활보하는 무결성 붕괴가 일어난다. 소셜 로그인 직후, 우리 앱만의 자체 세션이나 자체 JWT(Access Token)를 새로 발급하여 사용하는 것이 글로벌 아키텍처 원칙이다.
-
📢 섹션 요약 비유: 구글이 끊어준 출입증(ID Token)은 정문에 들어올 때 "나 구글 친구야"라고 증명하는 용도이지, 회사 내부 식당이나 회의실 문을 열고 다닐 때 쓰는 만능열쇠가 아닙니다. 일단 정문에 들어왔으면 우리 회사 전용 출입증(자체 Token)으로 바꿔 매고 다녀야 안전합니다.
Ⅴ. 기대효과 및 결론
정량/정성 기대효과
| 구분 | 자체 회원가입 구축 시 (과거) | OIDC 소셜 로그인 도입 시 | 개선 효과 |
|---|---|---|---|
| 정량 (전환율) | 아이디/비밀번호/이메일 인증 등 가입 절차 5단계 (이탈률 높음) | "카카오로 1초 만에 시작하기" 클릭 1번 | 신규 고객 회원가입 이탈률 50% 이상 감소 (폭발적 성장) |
| 정량 (보안 리스크) | 자체 DB에 사용자 비밀번호 저장 (해킹 시 회사 파산 위험) | 비밀번호 0건 저장 (구글/애플에 보안 책임 전가) | 비밀번호 유출에 따른 기업의 법적 책임/손해배상 100% 면제 |
| 정성 (데이터 품질) | 가짜 이메일, 가짜 전화번호 입력 난무 | 통신사 및 거대 플랫폼이 이미 실명 검증한 정보 획득 | 확보된 고객 데이터(Profile)의 질적 신뢰도 극대화 |
미래 전망 및 진화 방향
- Apple의 "Sign in with Apple" 강제 및 표준화: 애플은 앱스토어에 소셜 로그인(구글, 페이스북)을 하나라도 넣으려면 무조건 애플 로그인도 넣도록 정책을 강제했다. 이 애플 로그인의 뒷단 뼈대가 바로 OIDC 규격이다. OIDC는 거대 빅테크들의 독자 규격 전쟁을 멈추고 전 세계를 하나의 통일된 신원 연합(Identity Federation)으로 평정했다.
- 분산 신원 증명 (DID, Decentralized Identity)과의 경쟁 및 융합: OIDC의 유일한 단점은 "구글이나 카카오(OP)가 죽으면 전 세계 수십만 개의 앱 로그인이 동시에 죽는다"는 거대 플랫폼 종속성(SPOF)이다. 블록체인 기반으로 내 신원 정보를 내 폰에 직접 저장하는 DID 기술이 차세대 웹3.0(Web3) 인증으로 부상하고 있으나, 당분간은 사용자 편의성에서 압도적인 OIDC가 B2C 인증 시장을 철권통치할 것이다.
참고 표준
- OpenID Connect Core 1.0: OIDC 프로토콜의 핵심 규격 (OAuth 2.0 위에 ID Token과 UserInfo API를 어떻게 얹을지 정의).
- JWT (RFC 7519) / JWS (RFC 7515): ID Token의 형태(JSON)와 디지털 서명(Signature)을 검증하기 위한 암호학적 기반 IETF 표준.
결국 OIDC는 "권한"만 따지던 바보 같은 로봇(OAuth)에게 "그래서 네가 누군데?"라는 인간의 본질적 질문(신원)을 던질 수 있는 눈과 귀를 달아준 위대한 발명품이다. 번거로운 가입 절차 없이 클릭 한 번으로 수백 개의 앱을 옮겨 다니는 현대 스마트폰의 쾌적한 디지털 유목민 생활은, 오롯이 OIDC라는 보이지 않는 JSON 신분증 교환 인프라가 뒷받침하고 있기에 가능했다.
- 📢 섹션 요약 비유: 옛날엔 식당, 카페, 영화관을 갈 때마다 그 가게 전용 멤버십 카드를 새로 파야 해서 지갑이 터질 지경이었지만, OIDC라는 신용카드 하나로 통합되면서 세상 모든 가게 문을 '삑' 하고 1초 만에 열고 들어가는 마법의 패스 시대가 열린 것입니다.
📌 관련 개념 맵 (Knowledge Graph)
| 개념 명칭 | 관계 및 시너지 설명 |
|---|---|
| OAuth 2.0 | OIDC가 기생하여 동작하는 모체(숙주) 프레임워크로, 브라우저가 화면을 옮겨 다니는 리다이렉트 흐름(Dance)을 제공해 준다. |
| ID Token (신분증 토큰) | OIDC의 핵심 결과물이자 심장으로, 무거운 XML(SAML) 대신 가벼운 JSON에 서명을 더해(JWT) 사용자의 이름과 얼굴을 담아 넘겨주는 페이로드다. |
| SAML 2.0 | 회사와 회사(B2B)를 묶는 옛날 방식의 무거운 엔터프라이즈 SSO 기술이라면, OIDC는 일반인(B2C)과 스마트폰 앱을 묶는 빠르고 가벼운 SSO 기술이라는 완벽한 대척점이다. |
| JWT (JSON Web Token) | OIDC가 발급하는 ID Token의 데이터 포맷. 글자 수가 적어 HTTP 헤더나 URL에 실어 보내기 최적화된 마이크로서비스 시대의 공용어다. |
| UserInfo Endpoint | ID Token이 너무 뚱뚱해질까 봐 핵심 정보(이름, 이메일)만 넣고, 추가 정보(주소, 전화번호)는 Access Token을 들고 와서 따로 뽑아갈 수 있게 열어둔 OIDC 전용 API 창구다. |
👶 어린이를 위한 3줄 비유 설명
- 새로 나온 게임 앱에 가입하려고 비밀번호를 또 만들려니 귀찮고 까먹을까 봐 걱정되죠? 옛날엔 다 그렇게 불편했어요.
- 하지만 OpenID Connect(OIDC) 덕분에 게임 앱이 "구글 형님, 이 친구 누군지 대신 확인 좀요!"라고 구글에 부탁할 수 있게 되었어요.
- 구글이 "어, 이 친구 내 친구 길동이 맞아!"라고 도장이 쾅 찍힌 보증서(ID Token)를 게임 앱에 휙 던져주면, 우리는 비밀번호 없이 1초 만에 뿅 하고 게임에 로그인할 수 있답니다.