CS/INFRA

CloudFront 배포 후 로그인 풀림 현상 해결 (세션 쿠키 미저장 이슈)

ryukyungwoo1220 2025. 12. 24. 12:01

안녕하세요! 오늘은 AWS 인프라 구축 중에 겪었던 "로그인 세션이 자꾸 풀리는 문제"에 대한 트러블슈팅 과정을 기록으로 남겨두려 합니다.

로컬 환경(Localhost)에서는 아무 문제 없이 잘 되던 로그인이, AWS EC2에 배포하고 CloudFront(CDN)를 연결하자마자 로그인이 안 되거나 페이지 이동 시 바로 풀려버리는 현상이 발생했는데요.

범인은 바로 CloudFront의 캐시 정책브라우저의 쿠키 보안 정책이었습니다. 어떻게 해결했는지 정리해 보겠습니다.


1. 문제 상황 (Symptoms)

개발한 Admin 페이지를 배포한 후 다음과 같은 증상이 나타났습니다.

  • 🔐 로그인 풀림: Admin 로그인 성공 후, 다른 페이지로 이동하거나 뒤로가기를 누르면 로그인이 풀림.
  • 🍪 쿠키 실종: 브라우저 개발자 도구(F12) > Application > Cookies 탭을 확인해 보니 JSESSIONID가 저장되지 않음.
  • 🚫 401 에러: API 요청 시 인증 정보가 넘어가지 않아 401 Unauthorized 응답 발생.

2. 원인 분석

로그를 뜯어보고 설정을 확인해 본 결과, 두 가지 복합적인 원인이 있었습니다.

원인 1. CloudFront가 쿠키를 "배달 사고" 냄

기존 Terraform 코드에서 CloudFront의 설정을 forwarded_values (Legacy 방식)로 하고 있었습니다. 이 방식은 요청(Request) 시 쿠키를 백엔드로 보내주긴 하지만, 백엔드가 응답(Response)할 때 주는 Set-Cookie 헤더를 브라우저에게 제대로 전달하지 못하는 문제가 있었습니다. 즉, 중간 배달부(CloudFront)가 쿠키를 누락시킨 것이죠.

원인 2. 브라우저의 깐깐한 보안 정책 (HTTPS)

CloudFront를 통해 HTTPS로 통신하고 있었는데, 백엔드(Spring Boot)에서 세션 쿠키를 발급할 때 **보안 속성(Secure, SameSite 등)**을 명시하지 않았습니다. 최신 브라우저(Chrome 등)는 HTTPS 환경에서 보안 속성이 없는 쿠키는 "위험하다"고 판단하여 저장을 거부해버립니다.


3. 해결 방법 (Solution)

Step 1. CloudFront 정책 변경 (Terraform)

CloudFront의 구형 설정(forwarded_values)을 버리고, 최신 방식인 Cache PolicyOrigin Request Policy를 적용했습니다.

  • Cache Policy: API 응답은 캐시하지 않도록 설정 (min/max/default_ttl = 0)
  • Origin Request Policy: 쿠키(All), 헤더(AllViewer), 쿼리스트링(All)을 모두 백엔드로 통과시키도록 설정

📄 modules/cloudfront/main.tf

Terraform
 
# 1. API용 캐시 정책 생성 (캐시 안 함)
resource "aws_cloudfront_cache_policy" "api_no_cache" {
  name        = "homepage-dev-api-no-cache"
  comment     = "No caching for API"
  min_ttl     = 0
  default_ttl = 0
  max_ttl     = 0

  parameters_in_cache_key_and_forwarded_to_origin {
    cookies_config {
      cookie_behavior = "none"
    }
    headers_config {
      header_behavior = "none"
    }
    query_strings_config {
      query_string_behavior = "none"
    }
  }
}

# 2. 오리진 요청 정책 생성 (쿠키/헤더 모두 통과)
resource "aws_cloudfront_origin_request_policy" "api_all_cookies" {
  name    = "homepage-dev-api-all-cookies"
  comment = "Forward all cookies and headers to origin"

  cookies_config {
    cookie_behavior = "all"
  }
  headers_config {
    header_behavior = "allViewer"
  }
  query_strings_config {
    query_string_behavior = "all"
  }
}

# 3. CloudFront Behavior에 적용
resource "aws_cloudfront_distribution" "main" {
  # ... (생략)

  ordered_cache_behavior {
    path_pattern     = "/api/*"
    target_origin_id = "EC2-Backend"

    # 새로 만든 정책 ID 연결
    cache_policy_id          = aws_cloudfront_cache_policy.api_no_cache.id
    origin_request_policy_id = aws_cloudfront_origin_request_policy.api_all_cookies.id
    
    # ... (나머지 설정)
  }
}

Step 2. Spring Boot 쿠키 속성 강화

브라우저가 쿠키를 안전하게 저장할 수 있도록, docker-compose 환경변수를 통해 Spring Boot의 세션 쿠키 설정을 오버라이드했습니다.

📄 docker-compose.ec2.yml

YAML
 
backend:
  environment:
    # ... 기존 환경변수 ...
    
    # HTTPS 환경 필수 설정
    SERVER_SERVLET_SESSION_COOKIE_SECURE: "true"      # HTTPS에서만 쿠키 전송
    SERVER_SERVLET_SESSION_COOKIE_SAME_SITE: "lax"    # CSRF 방지 및 사이트 간 이동 허용
    SERVER_SERVLET_SESSION_COOKIE_PATH: "/"           # 모든 경로에서 쿠키 허용
    SERVER_SERVLET_SESSION_COOKIE_HTTP_ONLY: "true"   # 자바스크립트로 쿠키 접근 불가 (보안)

4. 결과 및 배운 점

위 설정을 적용하고 Terraform Apply 및 재배포를 진행한 결과,

  1. 브라우저 Application 탭에 JSESSIONID가 정상적으로 생성되었고,
  2. 페이지를 이동해도 로그인이 풀리지 않는 것을 확인했습니다! 🎉