Weekly Paper

Weekly Paper #13

승주우에요 2026. 6. 9. 09:59

1. 세션 기반 인증 vs 토큰 기반 인증

세션 기반 인증 (Session-based Authentication)

로그인 시 서버가 세션을 생성하고, 클라이언트는 세션 ID만 쿠키로 보관하는 방식입니다.

1. 클라이언트 → 로그인 요청
2. 서버 → 세션 생성 (서버 메모리/DB에 저장)
3. 서버 → 세션 ID를 쿠키로 응답
4. 클라이언트 → 이후 요청마다 쿠키(세션 ID) 포함
5. 서버 → 세션 ID로 서버에 저장된 세션 조회 → 인증 확인

장점

  • 서버에서 세션을 직접 관리하므로 즉시 무효화(로그아웃) 가능
  • 클라이언트에 민감한 정보가 남지 않음

단점

  • 서버가 여러 대면 세션 공유 문제 발생 (Redis 같은 세션 스토리지 필요)
  • 서버 메모리 사용량 증가
  • 모바일 앱, 타 도메인 API 호출에 쿠키 사용이 불편

보안 고려사항

  • HTTPS 필수 (쿠키 탈취 방지)
  • HttpOnly, Secure 쿠키 속성 설정
  • 세션 고정 공격 방지: 로그인 성공 시 세션 ID 재발급
  • 세션 만료 시간 설정

토큰 기반 인증 (Token-based Authentication / JWT)

로그인 시 서버가 토큰을 발급하고, 클라이언트가 토큰을 직접 보관하는 방식입니다.

1. 클라이언트 → 로그인 요청
2. 서버 → JWT 토큰 생성 후 응답 (서버에 저장 X)
3. 클라이언트 → 토큰을 로컬스토리지 또는 메모리에 저장
4. 클라이언트 → 이후 요청마다 Authorization: Bearer {token} 헤더에 포함
5. 서버 → 토큰 서명 검증만으로 인증 확인 (DB 조회 X)

장점

  • 서버가 상태를 저장하지 않음 (Stateless) → 수평 확장 용이
  • 모바일, 타 도메인 API 호출에 적합
  • 마이크로서비스 환경에서 서비스 간 인증 전달 편리

단점

  • 토큰 발급 후 즉시 무효화 불가 (만료 전까지 유효)
  • 토큰 크기가 세션 ID보다 큼
  • 탈취 시 만료 전까지 악용 가능

보안 고려사항

  • Access Token 만료 시간 짧게 설정 (15분~1시간)
  • Refresh Token으로 재발급 구조 구성
  • 토큰은 HttpOnly 쿠키에 저장 (XSS 방지)
  • 로컬스토리지 저장은 XSS에 취약하므로 지양
  • 알고리즘은 HS256 이상 사용

비교 정리

항목 세션 기반 토큰 기반

상태 저장 위치 서버 클라이언트
확장성 낮음 (세션 공유 필요) 높음 (Stateless)
즉시 무효화 가능 어려움
모바일/API 적합성 낮음 높음
주요 보안 위협 세션 탈취, 고정 공격 토큰 탈취, XSS

2. OAuth 2.0

OAuth 2.0이란?

사용자가 비밀번호를 직접 제공하지 않고, 제3자 애플리케이션에 제한적인 접근 권한을 위임하는 표준 프로토콜입니다.

예: "구글 계정으로 로그인" 버튼을 누를 때 OAuth 2.0이 동작합니다.


주요 컴포넌트

컴포넌트 역할 예시

Resource Owner 실제 사용자 나 (사용자)
Client 권한을 요청하는 앱 우리가 만든 서비스
Authorization Server 인증 및 토큰 발급 Google, Kakao
Resource Server 보호된 자원을 가진 서버 Google API 서버

Authorization Code Grant 흐름

가장 안전하고 많이 쓰이는 방식입니다.

[1] 사용자 → 우리 서비스: "구글로 로그인" 클릭

[2] 우리 서비스 → Authorization Server:
    GET /oauth/authorize
    ?response_type=code
    &client_id=abc123
    &redirect_uri=https://ourapp.com/callback
    &scope=email profile

[3] Authorization Server → 사용자: "우리 앱이 이메일/프로필 접근을 요청합니다. 허용?"

[4] 사용자 → Authorization Server: 허용 클릭

[5] Authorization Server → 우리 서비스:
    GET https://ourapp.com/callback?code=AUTHORIZATION_CODE

[6] 우리 서비스 → Authorization Server:
    POST /oauth/token
    { code: AUTHORIZATION_CODE, client_secret: xxx }

[7] Authorization Server → 우리 서비스:
    { access_token: "...", refresh_token: "..." }

[8] 우리 서비스 → Resource Server:
    GET /userinfo
    Authorization: Bearer access_token

[9] Resource Server → 우리 서비스: 사용자 정보 반환

왜 Code를 먼저 받고 Token을 따로 요청하나?

[5] → [6] 단계를 보면 Access Token을 바로 주지 않고 Authorization Code를 먼저 줍니다.

이유는 보안 때문입니다.

  • Authorization Code는 브라우저 URL에 노출됨 (짧은 유효시간, 1회용)
  • Access Token은 서버 간 통신(백채널)으로만 교환 → URL에 절대 노출되지 않음
  • client_secret을 포함해야 토큰 발급 가능 → 클라이언트 검증

PKCE (Proof Key for Code Exchange)

모바일 앱이나 SPA처럼 client_secret을 안전하게 보관할 수 없는 환경에서 사용합니다.

1. 클라이언트가 code_verifier (랜덤 문자열) 생성
2. code_verifier를 해시한 code_challenge를 인증 요청에 포함
3. 토큰 요청 시 원본 code_verifier 전송
4. 서버가 해시해서 비교 → 중간자 공격 방지

'Weekly Paper' 카테고리의 다른 글

Weekly Paper #15  (0) 2026.06.09
Weekly Paper #14  (0) 2026.06.09
Weekly Paper #12  (0) 2026.05.11
Weekly Paper #10  (0) 2026.04.01
Weekly Paper #9  (0) 2026.03.23