OpenID Connect

개요

OpenID Connect(OIDC)는 OAuth 2.0 위에 '인증(누구인가)' 계층을 얹은 표준입니다. OAuth가 '무엇을 할 수 있는가'만 다뤘던 빈틈을 메워, ID Token이라는 서명된 JWT로 사용자의 신원을 검증 가능한 형태로 전달합니다. 'Google/Apple/카카오로 로그인' 버튼 뒤에 있는 프로토콜이 바로 이것입니다.

전송 방식

Authorization: Bearer <access_token> + ID Token (JWT) from the token endpoint

자세히

OAuth와 흐름은 같지만 scope에 `openid`를 포함해 요청하면, 토큰 엔드포인트가 access token과 함께 ID Token(JWT)을 돌려줍니다. 이 ID Token의 클레임에는 발급자(iss), 사용자 식별자(sub), 대상 클라이언트(aud), 만료(exp), 인증 시각(auth_time), 그리고 요청 시 넣은 nonce가 들어 있어, 클라이언트가 '이 토큰이 우리 앱을 위해, 신뢰하는 IdP가, 방금 발급했다'를 확인할 수 있습니다.

access token은 리소스 서버(API)를 위한 것이고 ID Token은 클라이언트(앱)를 위한 것이라는 역할 구분이 중요합니다. 앱은 ID Token을 API로 보내면 안 되고, API에는 access token을 보냅니다. 사용자 프로필 정보가 더 필요하면 access token으로 표준 `/userinfo` 엔드포인트를 호출합니다. IdP 메타데이터는 `/.well-known/openid-configuration`에서, 서명 검증용 공개키는 JWKS 엔드포인트에서 자동 발견됩니다.

핵심 원칙: 로그인(인증)이 필요하면 OAuth access token의 존재로 판단하지 말고 반드시 OIDC ID Token을 검증하세요. access token만 보고 사용자를 로그인시키면, 다른 서비스용으로 발급된 토큰이 재사용되는 등의 취약점(confused deputy)에 노출됩니다.

요청 / 응답 예시

id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkayJ9.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJzdWIiOiIyNDgyODkiLCJhdWQiOiJhYmMxMjMiLCJleHAiOjE2MDk0NTkyMDB9.<sig>

코드로 보기

GET /authorize?response_type=code&client_id=abc123
  &redirect_uri=https://app.example.com/cb
  &scope=openid%20profile%20email&state=xyz&nonce=n-0S6_WzA2Mj HTTP/1.1
Host: auth.example.com
import { jwtVerify, createRemoteJWKSet } from 'jose';
const JWKS = createRemoteJWKSet(new URL('https://auth.example.com/.well-known/jwks.json'));
const { payload } = await jwtVerify(idToken, JWKS, {
  issuer: 'https://auth.example.com',
  audience: 'abc123'
});
if (payload.nonce !== savedNonce) throw new Error('nonce mismatch');

보안 고려사항

관련 헤더

관련 상태코드