백엔드 면접 용어 사전
인증·인가OpenID Connect

OIDC

OAuth 2.0 위에 ID 토큰을 얹어 인증까지 표준화한 규격.

OAuth 2.0 위에 "이 사용자가 누구인가" 를 표준화해 얹은 인증 규격 (OpenID Connect).

왜 필요했나

OAuth 2.0은 인가 프로토콜이다. Access Token은 "이 앱이 자원에 접근해도 된다"는 증표일 뿐, 누구인지를 담고 있지 않다.

그런데 실무에서는 "구글로 로그인"이 필요했다. 각 회사가 제각각 방식으로 사용자 정보를 얻어 쓰다 보니

페이스북: GET /me

  • 구글: — GET /userinfo
  • 카카오: — GET /v2/user/me
  • 제공자마다 다른 구현. 표준이 없다

게다가 Access Token만으로 로그인을 처리하면 보안 문제가 있다

OIDC가 이것을 표준화했다.

무엇을 더했나 — ID Token

OAuth 2.0  →  Access Token  (자원 접근용)
OIDC       →  Access Token + ID Token  (누구인지 증명)

ID Token은 서명된 JWT이며 사용자 정보를 담는다.

{
  "iss": "https://accounts.google.com",   // 발급자
  "aud": "내앱의-client-id",               // 대상 ★
  "sub": "1234567890",                    // 사용자 고유 ID ★
  "email": "user@example.com",
  "email_verified": true,
  "nonce": "무작위값",                     // 재생 공격 방지 ★
  "exp": 1700000000,
  "iat": 1699996400
}

Access Token으로 로그인하면 안 되는 이유

OAuth 항목에서 언급한 confused deputy 문제를 구체적으로 보자.

  • ① 공격자가 자기 앱 "악성앱"을 만들고 피해자에게 구글 로그인을 시킨다
  • ② 악성앱은 피해자의 Access Token을 얻는다
  • ③ 그 토큰을 들고 우리 서비스에 "구글 로그인" 시도
  • ④ 우리 서비스가 토큰으로 /userinfo 를 호출 → "피해자입니다" 응답
  • ⑤ 피해자 계정으로 로그인 성공 ✗

Access Token에는 "누구를 위해 발급됐는지"가 없어서 생기는 문제다.

ID Token에는 aud(대상) 가 있다. 우리 서비스는 aud가 자기 client_id와 일치하는지 검증하므로, 다른 앱용 토큰은 거부된다.

반드시 검증해야 할 것들

  • 서명 — — 제공자의 공개키(JWKS 엔드포인트)로 검증
  • iss — — 기대한 발급자인가
  • aud — — 내 client_id 와 일치하는가 ★ 가장 중요
  • exp — — 만료되지 않았는가
  • nonce — — 내가 보낸 값과 같은가 (재생 공격 방지)

라이브러리를 쓰되 이 검증들이 실제로 켜져 있는지 확인해야 한다.

표준 엔드포인트

  • /.well-known/openid-configuration ← 설정 자동 발견
  • /authorize — ← 인증 요청
  • /token — ← 토큰 교환
  • /userinfo — ← 추가 사용자 정보
  • /jwks — ← 서명 검증용 공개키

/.well-known/openid-configuration 덕분에 제공자를 바꿔도 설정을 하드코딩할 필요가 없다. 이 표준화가 OIDC의 실질적 가치다.

scope

  • openid — ← 필수. 이게 있어야 OIDC로 동작한다
  • profile — ← 이름, 사진 등
  • email — ← 이메일

openid scope가 없으면 그냥 OAuth 2.0이고 ID Token이 안 나온다.

사용자 식별은 sub로

❌ 이메일로 사용자 식별

  • 이메일은 바뀔 수 있다. 다른 사람에게 재할당될 수도 있다

✅ (iss, sub) 조합으로 식별

  • sub는 제공자 내에서 영구 불변
  • iss까지 봐야 하는 이유: 다른 제공자의 sub와 겹칠 수 있다

우리 DB에는 provider + provider_user_id 를 유니크 키로 두고, 이메일은 부가 정보로 저장한다.

면접 답변 골격

"OAuth 2.0은 인가, OIDC는 그 위의 인증 규격입니다. 소셜 로그인을 붙일 때 Access Token으로 사용자를 판단하면 aud 검증이 불가능해 다른 앱의 토큰으로 로그인당할 수 있어, ID Token을 검증해서 씁니다. 식별자는 이메일이 아니라 (iss, sub) 를 씁니다."

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 인증·인가 — 세션·JWT·OAuth 2.1·CSRF