개념을 먼저 레이어로 분리
HTTP에서 인증을 얘기할 때는 보통 아래 4축으로 보면 정리가 빠름
- 자격 증명을 매 요청에 직접 보내는 방식
- 서버가 저장한 상태를 식별자로 조회하는 방식
- 토큰 자체를 검증하는 방식
- 외부 인증 또는 권한 위임 프레임워크를 이용하는 방식
조금 더 구조적으로 나누면 다음처럼 분류 가능함
- Credential-based
- Basic Auth
- Digest Auth
- API Key
- Client Certificate mTLS
- Stateful Identifier-based
- Session ID
- Opaque Token
- Stateless Token-based
- JWT
- PASETO
- 기타 signed token
- Authentication / Authorization Framework
- OAuth 2.0
- OpenID Connect
- SAML HTTP 기반 웹 SSO 맥락
여기서 중요한 건 인증과 인가, 전달 메커니즘이 섞여서 헷갈리는 경우가 많다는 점임
인증(Authentication), 인가(Authorization), 전달 수단
- 인증은 너 누구냐를 확인하는 것
- 인가는 너 이거 할 권한 있냐를 판단하는 것
- 세션 또는 토큰 전달 메커니즘은 인증 결과를 HTTP 요청에 어떻게 실어 보내는지에 해당
전달 예시는 다음처럼 볼 수 있음
- Authorization 헤더
- Cookie
- 커스텀 헤더
- TLS 인증서
그래서 아래처럼 맵핑이 자주 섞여도 의미는 레이어가 다름
- JWT는 토큰 형식
- Cookie는 전달 수단
- OAuth2는 권한 위임 프레임워크
- Session은 서버 상태 저장형 인증 모델
1차 분류 기준은 서버가 상태를 저장하냐
이 기준이 제일 큼
Stateful Authentication
서버가 상태를 저장함
흐름은 대략 다음 형태
- 클라이언트가 식별자 토큰 또는 세션 id를 보냄
- 서버가 DB Redis session store에서 조회
- 사용자 확인
대표 예시
- Session ID
- Opaque Token
- API Key 운영에 따라
- DB 조회형 access token
장점은 강제 로그아웃이 쉽고 토큰 폐기 revoke가 쉬운 편이라는 점 권한 변경도 즉시 반영하기 쉬움 중앙 통제가 쉬운 편도 장점으로 자주 언급됨
단점은 저장소 필요, 매 요청 lookup 비용, 수평 확장 시 공유 저장소가 필요할 수 있다는 점
Stateless Authentication
서버는 별도 상태를 안 저장해도 됨
흐름은 다음
- 클라이언트가 토큰을 보냄
- 서버가 토큰 자체를 검증
- 사용자 확인
대표 예시
- JWT
- PASETO
- 서명된 자체 토큰
장점은 lookup 없이 검증 가능하고 분산 시스템에 유리하다는 점 마이크로서비스 환경에서 편한 이유가 여기 있음
단점은 토큰 폐기 어렵고 권한 변경이 즉시 반영되기 어려우며 탈취 시 만료 전까지 위험할 수 있다는 점
2차 분류 기준은 자격 증명을 무엇으로 증명하냐
ID/PW 같은 원시 자격 증명을 직접 보내는 방식
Basic Authentication
가장 단순한 HTTP 인증 방식
예시는 다음 형태
- Authorization: Basic base64 username password
동작은 매 요청마다 ID와 PW를 보내고 서버가 그걸 검증하는 구조임
장점
- 단순함
- 표준 지원이 쉬움
- 테스트용으로 편함
단점
- 사실상 비밀번호를 반복 전송
- HTTPS 없으면 매우 위험
- 로그아웃 또는 세션 관리 개념이 약함
- 실서비스 사용자 인증에는 부적합
적합한 경우는 내부 시스템, 개발 테스트, 간단한 사내 툴, 다른 인증 앞단의 임시 보호막 정도로 보는 편이 현실적임
Digest Authentication
Basic보다 개선된 옛 방식 비밀번호 원문 대신 challenge response 형태로 검증하는 구조로 설계됨
장점은 Basic보다 안전하도록 설계됐다는 점
단점은 현대 웹에서 거의 안 쓰고 구현 호환성 운영성 애매함이 큼 TLS 보편화 이후 존재감이 많이 줄었다고 보면 됨
지금은 HTTP 인증의 역사적 방식 정도로 이해하면 충분함
식별자만 보내고 서버가 조회하는 방식
Session Authentication
서버가 로그인 상태를 저장하고 클라이언트는 그 상태를 가리키는 식별자만 보냄
전달은 다음처럼 가능
- session_id -> server-side session data
- Cookie: session_id=abc123
- Authorization: Bearer abc123
여기서 본질은 쿠키가 아니라 서버 상태 저장임
서버 예시는 이런 식으로 이해하면 됨
- abc123 -> user_id, login_at, csrf_secret, roles
장점은 강제 로그아웃이 쉬우며 세밀한 세션 관리도 쉬움 권한 변경 반영도 빠르고 민감 정보가 클라이언트로 직접 내려가지 않는 편임
단점은 저장소 필요, sticky session 또는 central store 필요, 대규모 분산 환경에서 관리 비용이 생길 수 있음
자주 쓰는 환경은 전통적인 웹앱, SSR 중심 서비스, 브라우저 쿠키 기반 로그인임
Opaque Token
랜덤한 문자열만 주고 서버가 그 값을 조회하는 방식
예시는 다음 형태
- Authorization: Bearer x8f1a92…
서버 조회는 이런 구조로 생각하면 됨
- x8f1a92… -> user_id, scope, expires_at
본질은 세션과 같은 상태 저장형 토큰임
장점
- revoke가 쉬움
- 토큰 내용 노출이 없음
- 중앙 제어가 쉬움
- OAuth ecosystem과 잘 맞음
단점
- 매 요청 조회 필요
- 독립 검증이 불가
- 인프라 부담이 생김
자주 쓰는 환경은 API access token, OAuth2 introspection 기반, 중앙 인증 서버 구조임
Session과 Opaque Token 관계
핵심은 둘 다 상태를 가리키는 opaque identifier라는 점 차이는 보통 용어를 어느 맥락에서 쓰는지, Cookie로 보내는지 Authorization 헤더로 보내는지, 웹 로그인 세션인지 API access token인지 정도로 정리하면 깔끔함
토큰 자체를 검증하는 방식
JWT
토큰 자체에 정보가 들어 있고 서버는 서명 검증만 수행하는 쪽임
구조는 다음
- header.payload.signature
전달 예시는 다음 형태
- Authorization: Bearer
구성
- Header는 알고리즘과 타입
- Payload는 사용자 권한과 만료 시간 같은 claim
- Signature는 위변조 방지
장점
- 서버 lookup 없이 검증 가능
- 서비스 간 공유가 쉬움
- 분산 환경에 강함
단점
- revoke가 어려움
- payload는 보통 읽을 수 있음
- 잘못 설계하면 토큰 비대화
- 권한 변경이 즉시 반영되기 어려움
자주 쓰는 환경은 SPA + API, 모바일 앱 + API, 마이크로서비스, OIDC id_token 또는 access token
PASETO
JWT 대안으로 많이 언급되는 포맷
JWT보다 더 안전한 기본 설계를 지향하는 방향으로 설명되는 편임
장점
- 알고리즘 혼동 위험을 줄임
- 설계가 비교적 보수적인 편
단점
- 생태계가 JWT보다 작음
- 실무 표준성은 JWT 쪽이 더 강한 편
단순 식별용 인증
API Key
보통 사용자 로그인보다는 애플리케이션 또는 소비자 식별에 가까움
전달 예시
- X-API-Key: sk_abc123
- Authorization: ApiKey sk_abc123
인증 대상은 사람보다는 앱, 파트너, 서버, 프로젝트 쪽임
장점
- 매우 단순
- 발급, 회전, 사용이 쉬움
- 서버 간 연동에 적합
단점
- 사용자 인증 표현력이 낮음
- 세밀한 권한 체계 제한적
- 키 유출 시 위험이 큼
- 보통 소유 증명 proof of possession이 없음
자주 쓰는 환경은 Public API, 파트너 API, 내부 서비스 간 호출, 백엔드 잡 또는 스크립트
TLS 계층에서 인증
Mutual TLS mTLS
HTTP 메시지에 토큰을 넣는 게 아니라 TLS 핸드셰이크 단계에서 클라이언트 인증서를 검증하는 방식
구조
- 서버도 인증서를 가짐
- 클라이언트도 인증서를 가짐
- 상호 검증
장점
- 신뢰가 매우 강함
- 토큰 탈취형 공격에 상대적으로 강함
- machine-to-machine에 매우 적합
단점
- 인증서 발급, 배포, 회전, 폐기가 어려움
- 운영 복잡도가 높음
- 일반 사용자 앱에는 과한 경우가 많음
자주 쓰는 환경은 금융 인프라, 내부 고신뢰망, 서비스 간 통신, B2B 고보안 API
프레임워크 또는 프로토콜 계층
이 구간은 인증 방식이라기보다 인증 또는 인가를 조직하는 상위 규격에 가까움
OAuth 2.0
OAuth 2.0은 권한 위임 프레임워크 사용자가 자기 비밀번호를 제3자 앱에 직접 주지 않고 제한된 권한만 위임하는 흐름을 정의함
중요한 점은 OAuth 2.0 자체가 토큰 포맷을 강제하지 않는다는 점 access token은 JWT일 수도 있고 opaque token일 수도 있음
OAuth 2.0이 제공하는 것
- 토큰 발급 흐름
- scope 개념
- client 인증
- refresh token
- authorization grant
즉 OAuth 2.0은 어떻게 토큰을 발급하고 어떻게 위임하느냐에 더 가깝다
OpenID Connect OIDC
OIDC는 OAuth 2.0 위에 사용자 로그인, 즉 신원 계층을 올린 것
- OAuth 2.0은 권한 위임
- OIDC는 로그인과 identity 표준화
특징
- id_token을 정의함
- id_token은 대개 JWT
- 사용자 프로필 또는 신원 식별을 표준화
자주 쓰는 환경은 소셜 로그인, SSO, 엔터프라이즈 로그인, Login with Google Microsoft Apple 같은 케이스
SAML
주로 기업 SSO, 브라우저 기반 웹 SSO에서 많이 쓰였던 방식 XML 기반 assertion을 주고받는 구조로 설명됨
특징은 엔터프라이즈 환경에서 강세가 있었고 오래된 기업 시스템에서 아직 중요하며 현대 API에서는 OAuth 2.0 또는 OIDC가 더 일반적이라는 흐름
전달 방식과 인증 모델은 별개
Cookie
- 브라우저 저장 및 전달 메커니즘
- 인증 방식 자체는 아님
Cookie로 담을 수 있는 것
- session id
- opaque token
- jwt
- csrf 관련 값
Authorization 헤더
- HTTP 헤더 전달 방식
- 역시 인증 방식 자체는 아님
예시
- Authorization: Basic …
- Authorization: Bearer …
- Authorization: ApiKey …
같은 인증 모델도 전달 방식은 달라질 수 있음
- Session ID를 Cookie로 보낼 수도 있고
- Session ID를 Authorization으로 보낼 수도 있음
- JWT를 Cookie에 담을 수도 있고
- JWT를 Authorization에 담을 수도 있음
요약 비교 관점
좋음은 단일 정답이 아니라 어떤 문제를 푸는지가 다름
- 웹 로그인은 보통 Session + Cookie 또는 OIDC 로그인 + session 또는 JWT를 cookie에 담아 운영
- REST API는 주로 Bearer JWT, Bearer Opaque Token, API Key, OAuth 2.0 client credentials, mTLS 조합을 자주 봄
- 서버 간 통신은 API Key, OAuth 2.0 client credentials, JWT client assertion, mTLS가 함께 언급됨
- 기업 SSO는 보통 OIDC 또는 SAML
마무리 정리
이 글의 핵심은 HTTP 인증을 레이어와 기준으로 나눠서 보면 혼동이 줄어든다는 점임
HTTP 인증은 크게 다음처럼 보면 깔끔함
- Basic Digest처럼 자격 증명 직접 전송
- Session Opaque처럼 서버 상태 조회
- JWT PASETO처럼 토큰 자체 검증
- OAuth 2.0 OIDC SAML처럼 상위 인증 프레임워크
- mTLS처럼 TLS 계층 인증
그리고 REST API에서는 특히 Opaque Token, JWT, API Key, OAuth 2.0, mTLS가 많이 보이는 편임