AquilaLog
OAuth2.0OIDCJWT연동소셜로그인

OAuth 2.0만으로는 왜 로그인이 부족할까 (OIDC)

aquila profile image
aquila
2026.03.24 02:06수정 2026.04.09 10:59조회 11
댓글 0조회11

요약: OAuth 2.0은 리소스 접근 권한을 위임하기 위한 프레임워크이고, OIDC는 그 위에 사용자 인증 계층을 얹은 표준입니다. 둘은 함께 자주 쓰이지만, 해결하려는 문제는 분명히 다릅니다. 이 글은 OAuth 2.0과 OIDC의 차이를 개념으로만 설명하지 않고, 왜 OAuth 2.0만으로는 로그인 구현이 아쉬운지, 왜 실무에서는 OIDC가 더 자연스러운 선택이 되는지, 그리고 현재 프로젝트 구조에서는 어떤 방식이 가장 잘 맞는지까지 한 번에 정리한 기록입니다.

시작하며

OAuth 2.0과 OIDC는 처음 접하면 이름부터 헷갈립니다.

둘 다 토큰을 주고받고, 둘 다 외부 계정 로그인 이야기에서 자주 등장하고, 실제로 구글 로그인 같은 기능도 이 둘 위에서 동작하니까요.

그래서 처음에는 자연스럽게 이런 질문을 하게 됩니다.

"구글 로그인은 OAuth 2.0인가, OIDC인가?"

겉으로 보면 둘 다 비슷해 보이지만, 출발점은 다릅니다.

  • OAuth 2.0은 사용자가 어떤 리소스에 접근할 수 있도록 권한을 위임하는 데 초점이 있습니다.
  • OIDC는 그 위에 사용자가 누구인지 확인할 수 있도록 인증 정보를 표준화합니다.

즉, 둘은 경쟁 관계가 아니라 목적이 다른 채로 함께 쓰이는 관계에 가깝습니다.

이번 글에서는 OAuth 2.0과 OIDC를 따로 외우는 대신, 왜 둘이 함께 등장하는지, 어디서부터 역할이 갈리는지, 실무에서 왜 OIDC 관점으로 설계해야 하는지를 흐름 중심으로 정리해보겠습니다.

특히 이 프로젝트처럼 이미 내부 JWT(access) + refresh(HttpOnly 쿠키) 구조가 있는 경우라면, 외부 인증 도입에서 더 중요한 것은 "토큰을 받아오는 것"보다 외부 사용자의 신원을 얼마나 안정적으로 검증할 수 있느냐였습니다.


TL;DR

항목OAuth 2.0OIDC
핵심 목적인가 (Authorization)인증 (Authentication) + 인가 보조
무엇을 증명하나"이 리소스에 접근할 수 있는가""이 사용자가 누구인가"
대표 토큰Access TokenID Token + Access Token
사용 예시외부 API 접근 권한 위임소셜 로그인, SSO, 사용자 인증
실무 결론API 권한 위임에는 적합로그인 구현에는 사실상 표준에 가까움

먼저 결론부터 — 이 프로젝트에서는 OIDC 우선이 맞았다

이번 로그인 도입에서 우리의 핵심 목표는 명확했습니다.

외부 계정으로 안전하게 로그인시키는 것.

반대로 핵심 목표가 아니었던 것은 이것입니다.

외부 API 사용 권한을 위임받아 다른 리소스를 대신 호출하는 것.

즉, 구글 드라이브 파일을 읽어오거나 캘린더 권한을 위임받는 시나리오가 아니라, 사용자의 신원을 확인해 우리 서비스의 회원으로 연결하는 것이 더 중요했습니다.

현재 구조도 이를 뒷받침했습니다.

  • 백엔드는 이미 내부 JWT(access) + refresh(HttpOnly 쿠키) 체계를 가지고 있음
  • 프론트는 /auth/me, /auth/refresh 기반 세션 복원 흐름이 준비되어 있음
  • 따라서 외부 인증은 초기 신원 확인만 맡고, 이후 세션 유지는 내부 토큰 체계로 이어지는 구성이 가장 자연스러움

이 기준으로 보면 선택지는 사실 많이 남지 않았습니다.

  • OAuth 2.0만 쓰면 권한 위임은 가능하지만, 신원 검증이 제공자별 API 응답에 더 많이 의존함
  • OIDC를 쓰면 ID Token 기반의 표준화된 신원 검증이 가능함

그래서 최종 결론은 다음과 같았습니다.

이 프로젝트의 로그인 도입 목적이라면 OIDC 우선이 맞습니다.

정확히는 "OAuth 2.0 흐름을 사용하되, 인증 시나리오는 OIDC로 구현한다"가 가장 적절한 선택이었습니다.


왜 OAuth 2.0만으로 로그인 설명이 자꾸 헷갈렸을까

처음 OAuth 2.0을 배울 때는 이렇게 이해하기 쉽습니다.

"토큰을 받아오고, 그걸로 로그인하면 되는 것 아닌가?"

실제로도 많은 로그인 흐름은 OAuth 2.0처럼 보입니다.

사용자가 외부 제공자 로그인 화면으로 이동하고, 동의하고, 다시 우리 서비스로 돌아오고, 토큰을 받아오니까요.

그런데 기능이 구체화될수록 설명이 점점 애매해집니다.

  • Access Token은 원래 리소스 접근 권한을 위한 것인데, 우리는 이걸로 사용자 인증까지 설명하려고 함
  • 사용자 정보는 결국 provider의 userinfo 응답에 기대게 되는데, 필드 의미와 검증 방식이 제각각일 수 있음
  • "누가 로그인했는가"를 확인하려는데, 실제로는 "어떤 API를 호출할 수 있는가" 중심 토큰을 보고 있음

겉으로 보면 "소셜 로그인은 잘 돌아가는 것"처럼 보이지만, 실제로는 인가용 토큰으로 인증 문제까지 같이 풀려고 하면서 경계가 흐려지고 있었던 것입니다.

flowchart TD
    ROOT["OAuth 2.0만으로 로그인 설명이 애매해지는 이유"]
    ROOT --> A["Access Token은 본래 인가용 토큰"]
    ROOT --> B["신원 정보는 provider API 의존도가 큼"]
    ROOT --> C["검증 규칙이 플랫폼마다 달라짐"]
    ROOT --> D["인증과 인가의 책임이 섞이기 쉬움"]

이 지점에서 질문이 바뀌었습니다.

"권한 위임 말고, 사용자의 신원 자체를 표준화해서 검증할 방법은 없을까?"


OAuth 2.0 — 핵심은 '무엇을 할 수 있는가'

OAuth 2.0은 사용자가 자신의 자원에 대해 제3자 애플리케이션에 접근 권한을 위임할 수 있게 해주는 프레임워크입니다.

예를 들어 어떤 서비스가 사용자의 구글 드라이브 파일을 읽거나, 캘린더 일정을 가져와야 한다면 OAuth 2.0이 아주 자연스럽습니다.

이때 중요한 건 사용자의 상세 신원 정보가 아닙니다.

핵심은 딱 하나입니다.

"이 토큰이 이 API를 호출할 수 있는가?"

정리하면 OAuth 2.0의 관심사는 다음과 같습니다.

  • 목적: 리소스 접근 권한 위임
  • 대표 결과물: Access Token
  • 핵심 판단 기준: scope와 권한 범위
  • 중심 질문: 특정 API 호출이 허용되는가
Tip

OAuth 2.0의 Access Token은 "누구냐"를 설명하는 신분증이라기보다, "무엇을 할 수 있느냐"를 나타내는 출입증에 더 가깝습니다.

그래서 OAuth 2.0 자체는 훌륭한 규격이지만, 로그인 문제를 완전히 설명해 주지는 못합니다.


OIDC — OAuth 2.0 위에 인증 계층을 올리다

OIDC(OpenID Connect)는 바로 이 지점을 보완하기 위해 등장했습니다.

OAuth 2.0의 권한 위임 구조는 그대로 활용하되, 여기에 사용자가 누구인지 확인하는 표준 계층을 추가합니다.

즉, OIDC는 OAuth 2.0을 대체하는 것이 아니라, OAuth 2.0 위에서 인증 문제를 풀기 위해 확장된 표준입니다.

OIDC가 추가하는 핵심은 다음과 같습니다.

  • ID Token 제공
  • UserInfo Endpoint 같은 표준 엔드포인트 제공
  • sub, iss, aud, exp, nonce 같은 검증 가능한 클레임 제공
  • 사용자 신원 확인 절차를 명확한 규칙으로 통일
graph LR
    U["사용자"] --> A["클라이언트 애플리케이션"]
    A --> O["OAuth 2.0 / OIDC 제공자"]
    O --> T1["Access Token"]
    O --> T2["ID Token"]
    T1 --> R["리소스 서버 접근 권한"]
    T2 --> I["사용자 신원 확인"]

여기서 중요한 변화는 단순히 토큰이 하나 더 생긴 것이 아닙니다.

인증을 어떤 기준으로 검증해야 하는지가 분명해진 것이 핵심입니다.


진짜 차이 — Access Token으로는 '로그인'을 설명하기 어렵다

실무에서 가장 많이 생기는 오해는 Access Token만 있으면 로그인까지 설명할 수 있다고 생각하는 것입니다.

하지만 Access Token과 ID Token은 역할이 완전히 다릅니다.

토큰용도주 사용처
Access Token리소스 서버 API 호출 권한 증명리소스 서버
ID Token사용자 인증 결과와 신원 정보 전달클라이언트 애플리케이션

OAuth 2.0만으로 로그인 비슷한 것은 만들 수 있습니다.

보통은 Access Token을 받은 뒤 provider의 사용자 정보 API를 별도로 호출해 이메일이나 이름을 가져오는 방식이 됩니다.

하지만 이 방식은 다음 한계를 가집니다.

  • 사용자 정보 응답 형식이 제공자마다 다를 수 있음
  • 어떤 필드를 신뢰해야 하는지 규칙이 표준화되어 있지 않음
  • 인증에 필요한 검증 포인트가 구현마다 달라질 수 있음
  • 계정 연결 기준이 흔들리면 중복 계정이나 오매핑 위험이 생길 수 있음

반대로 OIDC에서는 ID Token 검증 규칙이 더 명확합니다.

  • 발급자 iss
  • 대상자 aud
  • 만료 시각 exp
  • 사용자 고유 식별자 sub
  • 요청-응답 연계를 위한 nonce
Warning

중요한 점은 Access Token으로 로그인 상태를 판별하려 들면 설계가 쉽게 꼬인다는 것입니다. 인증은 ID Token의 책임이고, 리소스 접근 권한은 Access Token의 책임으로 분리해서 봐야 합니다.


이 프로젝트에서 OIDC를 선택한 이유 — 기준은 신원 검증 안정성이었다

이번 의사결정에서 비교 기준은 단순히 "구현이 쉬운가"가 아니었습니다.

오히려 더 중요했던 것은 이것이었습니다.

외부 인증 결과를 우리 서비스의 계정 체계에 얼마나 안정적으로 연결할 수 있는가.

1) 목표 정의

현재 요구는 외부 계정으로 안전하게 로그인하는 것입니다.

핵심은 외부 리소스 API 권한 위임이 아니라, 우리 서비스 사용자 식별입니다.

2) 현재 인증 구조와의 적합성

백엔드는 이미 내부 JWT(access) + refresh 토큰 구조가 있습니다.

프론트도 /auth/me, /auth/refresh 흐름이 준비되어 있습니다.

즉, 외부 인증은 초기 신원 확인만 담당하고, 이후는 내부 토큰 체계로 전환하는 구조가 가장 자연스럽습니다.

3) 대안 비교

  • OAuth 2.0 단독

장점: 구현이 비교적 단순함 단점: provider별 userinfo 의존이 커지고, 신원 검증 규칙이 상대적으로 약함

  • OIDC

장점: id_token 기반으로 표준화된 검증 가능 단점: state, nonce, 토큰 검증 등 구현 항목이 조금 더 많음

4) 리스크 기준 평가

  • 계정 매핑 안정성: OIDC 우세
  • 보안 검증 가능성: OIDC 우세
  • 기존 JWT 구조와의 결합 용이성: OIDC 우세
  • 초기 구현 비용: OAuth 2.0 단독 우세

5) 최종 선택

결국 우리는 다음 방식을 택하는 것이 가장 적절하다고 판단했습니다.

  1. OIDC 채택
  2. Authorization Code + PKCE + state/nonce 검증 적용
  3. 외부 인증 성공 후 기존 AuthService내부 JWT/access-refresh 발급
  4. 예외적으로 OIDC 미지원 provider만 OAuth 2.0 + userinfo fallback 고려
Tip

핵심은 외부 인증을 세션 유지 수단으로 삼는 것이 아니라, 외부 인증을 신뢰 가능한 신원 확인 단계로 사용하는 것입니다. 이후 세션은 우리 서비스의 토큰 정책으로 일관되게 관리하는 편이 구조적으로 더 안정적이었습니다.


실무 흐름으로 보면 더 명확하다 — 최종 인증 흐름은 이렇게 본다

최종적으로 정리한 흐름은 아래와 같습니다.

sequenceDiagram
    participant U as User
    participant FE as Frontend
    participant BE as Backend
    participant P as Provider

    U->>FE: 소셜 로그인 버튼 클릭
    FE->>P: 인증 요청 \\(Authorization Code + PKCE\\)
    P-->>U: 로그인 및 동의 화면 제공
    U-->>P: 로그인 + 동의
    P-->>FE: Authorization Code 반환
    FE->>BE: code 전달
    BE->>P: code로 토큰 교환 요청
    P-->>BE: Access Token + ID Token 반환
    BE->>BE: ID Token 검증 \\(iss, aud, sub, exp, nonce\\)
    BE->>BE: 회원 조회 또는 신규 가입 처리
    BE-->>FE: 내부 Access JWT + Refresh 쿠키 발급

이 흐름의 핵심 포인트는 다음과 같습니다.

  • Provider는 사용자의 신원을 확인하는 단계까지 담당합니다.
  • 우리 백엔드는 ID Token을 검증해 외부 인증 결과를 신뢰합니다.
  • 그 이후 인증 상태 유지는 우리 서비스의 내부 JWT + refresh 체계로 이어집니다.

즉, 외부 인증과 내부 세션 관리의 역할이 깔끔하게 분리됩니다.


왜 OIDC가 실무에서 더 적합할까

이론적으로는 OAuth 2.0만으로도 로그인 비슷한 흐름을 구현할 수 있습니다.

그런데 운영과 유지보수 관점까지 포함하면 OIDC가 훨씬 설계하기 쉬운 이유가 있습니다.

1) 사용자 식별 기준이 명확해진다

OIDC에서는 provider + sub 조합처럼 안정적인 고유 식별 기준을 세우기 좋습니다.

이 점은 계정 연결과 중복 계정 방지에서 특히 중요합니다.

2) 보안 검증 지점이 분명하다

iss, aud, exp, nonce 같은 검증 포인트가 명확하므로, 무엇을 확인해야 하는지가 흐려지지 않습니다.

3) 제공자가 늘어나도 규칙을 통일하기 쉽다

구글, 애플, 카카오처럼 여러 provider를 붙이더라도, OIDC를 중심에 두면 인증 흐름을 더 일관되게 유지할 수 있습니다.

4) 기존 내부 인증 구조와 연결하기 좋다

이번 프로젝트처럼 내부 JWT 구조가 이미 있는 경우, 외부 인증을 OIDC로 처리하고 내부 토큰으로 브릿지하는 구성이 가장 자연스럽습니다.

flowchart TD
    A["OIDC 도입 효과"] --> B["신원 검증 표준화"]
    A --> C["계정 매핑 안정성 향상"]
    A --> D["다중 provider 대응 용이"]
    A --> E["내부 JWT 구조와 결합이 깔끔"]

그렇다고 항상 OIDC가 정답일까 — 아닙니다

여기서 중요한 건 "OIDC가 더 좋아 보인다"가 아니라, 무슨 문제를 풀고 있는가를 먼저 분리하는 것입니다.

OAuth 2.0만으로 충분한 경우

  • 사용자의 외부 리소스에 접근 권한만 필요할 때
  • 로그인 자체가 목적이 아닐 때
  • 특정 API 호출 권한 위임만 처리하면 될 때

예를 들면 드라이브 파일 읽기, 캘린더 접근 권한, 외부 저장소 업로드 권한 위임 같은 시나리오가 여기에 가깝습니다.

OIDC가 필요한 경우

  • 사용자가 누구인지 확인해야 할 때
  • 소셜 로그인이나 SSO를 구현할 때
  • 사용자 신원 정보를 표준화된 방식으로 다루고 싶을 때
  • 계정 연결과 보안 검증을 더 안정적으로 가져가야 할 때

즉, 로그인 기능이 들어가는 순간 OIDC를 우선 고려하는 것이 자연스럽습니다.


도입 전에 확인하면 좋았던 체크리스트

점검 항목OIDC 권장OAuth 2.0만으로 충분
핵심 목적사용자 로그인, SSO, 계정 식별외부 API 접근 권한 위임
중요한 검증 대상사용자 신원과 토큰 클레임scope와 리소스 접근 권한
계정 매핑 안정성provider + sub 기준이 중요함사용자 식별이 핵심이 아님
기존 인증 구조내부 세션/JWT 체계와 연결해야 함단발성 외부 권한 위임이면 충분
운영 리스크오인증, 계정 중복, 검증 누락 방지가 중요함리소스 권한 위임 실패 대응이 중심

한 번에 정리하는 핵심 구조

flowchart TD
    A["OAuth 2.0"] --> B["권한 위임"]
    A --> C["Access Token 발급"]
    D["OIDC"] --> E["OAuth 2.0 위에서 동작"]
    D --> F["ID Token 발급"]
    D --> G["사용자 신원 확인"]

이 그림만 기억해도 큰 흐름은 정리됩니다.

  • OAuth 2.0은 권한 위임을 해결합니다.
  • OIDC는 그 위에서 인증을 해결합니다.
  • 둘은 대체 관계가 아니라 확장 관계입니다.

마치며

OAuth 2.0과 OIDC는 이름이 비슷해서 자주 함께 묶이지만, 해결하는 문제는 분명히 다릅니다.

OAuth 2.0은 무엇을 할 수 있는가를 다루고, OIDC는 누구인가를 다룹니다.

실무에서는 둘이 함께 등장하기 때문에 경계가 흐려지기 쉽지만, 이 차이를 분명히 이해하고 나면 설계 방향도 훨씬 선명해집니다.

결론은 단순합니다.
  • OAuth 2.0은 권한 위임을 위한 프레임워크입니다.
  • OIDC는 OAuth 2.0 위에 인증 계층을 추가한 표준입니다.
  • 로그인처럼 사용자가 누구인지 확인해야 하는 순간에는 OIDC 관점으로 설계하는 것이 맞습니다.
  • 특히 내부 JWT 체계가 이미 있는 서비스라면, 외부 인증은 OIDC로 검증하고 내부 세션은 별도로 관리하는 구조가 가장 안정적입니다.

결국 중요한 것은 기술 이름을 외우는 것이 아니라, 인증과 인가의 책임을 섞지 않는 것이라고 생각합니다.

이 차이를 기준으로 보면, 어떤 토큰을 왜 검증해야 하는지도 훨씬 자연스럽게 이해할 수 있습니다.

목록으로 돌아가기

댓글

댓글 0