인증/인가(Authentication & Authorization) 개념 정리

정세현·2026년 7월 21일

NHN AX Internship Notes

목록 보기
4/16
post-thumbnail

OAuth 2.0 → OIDC → JWT → Keycloak → Spring Boot 소셜 로그인까지, 전체 흐름을 하나로 묶어서 정리


0. 큰 그림 먼저

OAuth 2.0   : 권한 위임의 표준 규격 (비밀번호 공유 없이 제3자에게 권한을 넘기는 방법)
    ↓ (위에 신원 확인 기능을 얹음)
OIDC        : OAuth 2.0 + "로그인(사용자가 누구인지 확인)"을 표준화한 확장판
    ↓ (OIDC의 산출물이 이 형식)
JWT         : OIDC/OAuth에서 실제로 주고받는 토큰의 데이터 형식 (서명된 JSON)
    ↓ (이 표준들을 실제로 구현한 소프트웨어)
Keycloak    : OIDC/OAuth 2.0을 구현한 오픈소스 인증 서버
    ↓ (실무에서 이걸 우리 서비스에 붙이는 방법)
Spring 소셜 로그인 : Spring Security가 OAuth2/OIDC 흐름을 처리해주는 실제 구현체

핵심 한 줄: OAuth는 뼈대, OIDC는 그 위의 로그인 표준, JWT는 데이터 형식, Keycloak은 이걸 구현한 서버, Spring Security는 우리 코드에서 이걸 다루는 방법.


1. OAuth 2.0 — 권한 위임의 표준

해결하려는 문제

제3자 앱(예: 노션)이 내 다른 서비스(예: 구글 캘린더) 데이터에 접근해야 할 때, 비밀번호를 그대로 넘기지 않고 필요한 권한만 안전하게 위임하기 위한 표준.

옛날 방식(비밀번호 직접 입력)의 문제점:

  • 비밀번호가 제3자 서버에 그대로 저장됨 → 유출 위험
  • 권한을 세분화할 수 없음 (전체 계정 접근 허용)
  • 취소하려면 비밀번호를 바꿔야 함 (다른 연동도 다 끊김)

등장인물 4명

역할설명예시
Resource Owner자원의 주인 (나)구글 계정 사용자
Client접근을 요청하는 제3자 앱노션
Authorization Server권한(토큰)을 발급하는 서버구글 인가 서버, Keycloak
Resource Server실제 보호된 데이터가 있는 서버구글 캘린더 API

기본 흐름 (개념)

  1. Client(노션)가 Authorization Server(구글)에 권한 요청
  2. Authorization Server가 Resource Owner(나)에게 "허락할래?" 확인
  3. 허락하면 Client에게 Access Token 발급
  4. Client는 이 토큰으로 Resource Server(캘린더 API)에 요청 → 데이터 획득

Scope (권한 범위)

권한을 통째로 주지 않고 잘게 쪼갠 단위로 부여.
예: calendar.read, calendar.write, email.read
→ Client는 필요한 scope만 요청, 사용자는 그 범위만 허락 여부 결정

Grant Type (권한 부여 방식)

상황별로 다른 흐름을 씀.

Grant Type언제 쓰나특징
Authorization Code웹/앱에서 사용자가 직접 로그인하는 경우 (가장 흔함)가장 안전, "구글로 로그인" 방식
Client Credentials서버 대 서버 통신, 사람 개입 없음배치 작업, 서버 간 API 호출
Refresh TokenAccess Token 재발급용Access Token은 수명이 짧고, 이걸로 재로그인 없이 갱신

중요: OAuth는 원래 "인증"용이 아니다

OAuth 2.0 자체는 "이 토큰이 이 권한을 가지고 있다"만 보장하지, "이 토큰을 가진 사람이 누구인지"는 표준 범위 밖이었음. 이 부분을 보완한 게 OIDC.


2. OIDC (OpenID Connect) — 로그인의 표준

정의

OAuth 2.0 위에 "사용자 신원 확인(로그인)" 기능을 추가로 표준화한 확장 규격.

  • OAuth만 쓰면: "이 앱이 이 권한을 가짐" (Access Token)
  • OIDC를 쓰면: "이 사용자가 진짜 누구인지" (ID Token, 즉 JWT)까지 표준 방식으로 제공

OAuth와의 차이

구분OAuth 2.0OIDC
목적권한 위임사용자 인증(로그인)
발급 토큰Access TokenAccess Token + ID Token
토큰 형식 규정자유ID Token은 반드시 JWT
"이 사람 누구야?"알 수 없음ID Token 안에 사용자 정보 포함

Keycloak과의 관계

Keycloak은 OIDC(및 OAuth 2.0) 규격을 실제로 구현한 서버 소프트웨어. 여러 앱이 각자 로그인 로직을 만들지 않고 Keycloak 하나로 통합 인증(SSO)을 구현할 수 있게 해줌.


3. JWT (JSON Web Token) — 토큰의 데이터 형식

구조

점(.)으로 구분된 3부분, 각각 Base64Url로 인코딩된 JSON.

eyJhbGciOiJSUzI1NiJ9 . eyJzdWIiOiIxMjM0NSJ9 . 서명값
   Header                  Payload              Signature
   (알고리즘 정보)          (실제 데이터, claim)   (위조 방지용 서명)
  • Header: 서명 알고리즘 정보 (예: RS256)
  • Payload: 사용자 정보, 만료시간(exp), 발급자(iss) 등 claim
  • Signature: Header + Payload를 발급자의 비밀키(또는 개인키)로 서명한 값. 검증자는 공개키로 이 서명을 검증

핵심 특징

서버가 DB를 조회하지 않고도, 서명만 검증하면 토큰의 진위를 확인할 수 있음.

→ 마이크로서비스 환경에서 서비스마다 "이 사용자 로그인 상태 맞아?"를 DB에 물어보지 않고 빠르게 검증 가능 (Stateless 인증).

주의할 점

  • JWT는 암호화된 게 아니라 인코딩(Base64)된 것 → Payload 내용은 누구나 디코딩해서 볼 수 있음 (비밀번호 같은 민감정보를 넣으면 안 됨)
  • 서명만 위조를 막아줄 뿐, 내용 자체를 숨기지는 못함
  • 확인은 jwt.io 에서 직접 디코딩해보면 이해가 빠름

4. Keycloak — 위 표준들을 구현한 인증 서버

역할

Red Hat이 만든 오픈소스 인증/인가 서버. OIDC, OAuth 2.0을 구현.

  • 회원가입, 로그인, 비밀번호 관리, 권한(Role) 관리를 앱마다 만들지 않고 중앙화
  • 여러 앱이 Keycloak 하나만 바라보면 SSO(싱글사인온) 구현 가능
  • 소셜 로그인(구글, 카카오 등) 연동도 Keycloak이 중간에서 대신 처리 가능
  • Role/Permission 기반 인가(Authorization) 관리

흐름 (Envoy Gateway와 연결 시)

마이크로서비스 아키텍처에서는 각 서비스가 개별적으로 JWT를 검증하지 않고, API Gateway(예: Envoy Gateway) 단에서 JWT 서명을 미리 검증하는 패턴을 많이 씀 → 검증 실패 시 뒤 서비스까지 요청이 도달하지 않아 각 서비스의 인증 로직 부담이 줄어듦.


5. Spring Boot 소셜 로그인(구글/카카오) 실제 동작

가장 헷갈리는 포인트

소셜 서비스(구글)의 Access Token ≠ 우리 서비스의 로그인 토큰. 완전히 별개다.

  • 구글 Access Token → "구글 API를 호출할 열쇠" (딱 사용자 정보 조회용으로만 잠깐 쓰고 버리는 경우가 많음)
  • 우리 서비스 JWT → 우리 API를 호출할 때 실제로 쓰이는, 우리가 직접 발급하는 토큰

단계별 흐름

1. 사용자가 "구글로 로그인" 클릭
   → Spring 앱이 구글 로그인 페이지로 리다이렉트
   → client_id, redirect_uri, scope(profile email 등)를 함께 전달

2. 구글 로그인 + 사용자 허락
   → 비밀번호 입력은 구글 페이지에서 발생 (Spring 앱은 비밀번호를 절대 못 봄)
   → 허락 시 구글이 redirect_uri로 authorization code를 붙여서 리다이렉트
     예: https://our-app.com/callback?code=abc123

3. Spring 서버가 code를 Access Token으로 교환 (서버 대 서버)
   POST https://oauth2.googleapis.com/token
   code=abc123
   client_id=...
   client_secret=...
   redirect_uri=...
   → client_secret이 필요해서 브라우저에서는 위조 불가능

4. 액세스 토큰으로 사용자 정보 조회 (액세스 토큰의 실질적 용도)
   GET https://www.googleapis.com/oauth2/v3/userinfo
   Authorization: Bearer {구글 액세스 토큰}
   → 이메일, 이름, 프로필 사진 등 획득. 여기서 역할 끝.

5. 우리 서비스의 회원가입/로그인 처리 + 자체 JWT 발급
   → 받은 이메일로 DB 조회 → 없으면 회원가입, 있으면 로그인
   → 우리 서비스 전용 JWT를 새로 발급해서 클라이언트에게 전달
   → 이후 우리 API 호출은 이 JWT로 인증

Spring Security 관점

  • spring-boot-starter-oauth2-client 의존성 추가 시 2~4번 과정이 대부분 자동화됨
  • 구글이 id_token(JWT)까지 함께 주면 OIDC 방식 → OidcUser로 처리
  • 순수 Access Token만 오는 경우 → OAuth2User로 처리
  • 소셜 로그인 사용자 DB 설계 시 보통 provider(google/kakao), provider_id 컬럼으로 구분

6. 용어 한눈에 정리

용어한 줄 정의
OAuth 2.0비밀번호 공유 없이 제3자에게 권한을 위임하는 표준
Access Token"이 권한을 가지고 있다"를 증명하는 토큰 (API 호출용)
ID Token"이 사용자가 누구인지"를 증명하는 토큰 (OIDC에서 추가됨, JWT 형식)
OIDCOAuth 2.0 + 로그인(신원 확인) 표준
JWT서명이 포함된 JSON 기반 토큰 형식 (Header.Payload.Signature)
KeycloakOIDC/OAuth 2.0을 구현한 오픈소스 인증 서버
SSO여러 앱을 하나의 인증 서버로 통합 로그인 처리하는 것
Scope요청/허용하는 권한의 범위 단위
Grant TypeOAuth에서 토큰을 발급받는 방식 (Authorization Code, Client Credentials 등)

7. 학습/실습 다음 단계

  1. Keycloak Docker로 로컬 실행 → Realm, Client 등록, 사용자 생성
  2. Postman/curl로 Authorization Code 흐름 직접 태워보고 JWT를 jwt.io에서 디코딩
  3. Spring Security + oauth2-client로 구글/카카오 로그인 붙여보기
  4. Spring Security Resource Server 설정으로 JWT 검증 로직 붙이기
  5. (심화) Envoy Gateway의 SecurityPolicy로 게이트웨이 단에서 JWT 검증하기
profile
I'm the best

0개의 댓글