Cookie / Session / SameSite / CORS
3줄 요약
- Cookie, Session, SameSite, CORS는 모두 “브라우저가 어떤 요청에 어떤 인증 정보를 붙일 수 있는가”를 결정하는 경계다.
- 백엔드에서 200을 응답해도 브라우저가 쿠키 저장, 쿠키 전송, CORS 노출, preflight 통과를 거부하면 프론트에서는 실패처럼 보인다.
- 실전 디버깅은
Set-Cookie, 실제 요청의 Cookie, Origin, preflight OPTIONS, CORS 응답 header, DevTools rejected reason을 같은 요청 흐름으로 묶어 확인한다.
핵심 정리
- Cookie는 서버가
Set-Cookie로 내려보내고 브라우저가 Domain, Path, Secure, HttpOnly, SameSite, 만료 조건을 만족하는 요청에 자동으로 붙이는 상태 전달 수단이다.
- Session은 cookie에 보통 session id만 두고 실제 인증 상태를 서버나 외부 저장소에 두는 방식이다. scale out, sticky session, Redis 같은 shared store, session fixation 방어를 함께 설계해야 한다.
- SameSite는 cross-site 요청에서 cookie 전송을 제한해 CSRF 위험을 줄인다. OAuth, 결제 redirect, 프론트/백 분리 구조에서는
SameSite=None; Secure가 필요한 상황과 위험을 같이 판단한다.
- CORS는 서버 간 통신 정책이 아니라 브라우저가 cross-origin 응답을 JavaScript에 노출할지 결정하는 정책이다. credential 요청에서는
Access-Control-Allow-Origin: *를 사용할 수 없다.
- Spring Security나 gateway가
OPTIONS preflight를 인증 필터로 막으면 실제 API까지 가지도 못하고 브라우저 요청이 실패한다.
헷갈리는 지점
curl로 API가 성공하면 브라우저도 성공한다고 생각하기 쉽다.
- 핵심 판단 포인트는 브라우저는 cookie 정책, CORS, mixed content, CSP, preflight를 추가로 적용한다는 것이다.
Set-Cookie가 응답에 있으면 쿠키가 저장됐다고 생각하기 쉽다.
- 핵심 판단 포인트는 DevTools의 cookie rejected reason에서 Secure, SameSite, Domain, Path, third-party cookie 정책 위반 여부를 확인하는 것이다.
- CORS 오류를 인증 실패와 같은 것으로 보기 쉽다.
- 핵심 판단 포인트는 CORS는 브라우저가 응답 노출을 막는 문제이고, 인증 실패는 서버가 401/403을 응답하는 문제라는 점이다.
SameSite=None으로 풀면 로그인 문제가 모두 해결된다고 생각하기 쉽다.
- 핵심 판단 포인트는 CSRF token, Origin/Referer 검증, HTTPS, cookie scope 최소화가 함께 있어야 한다.
확인 질문
- 브라우저에서
Set-Cookie가 내려왔는데 저장되지 않는다면 무엇을 먼저 확인해야 하는가?
- DevTools의 Application/Network 탭에서 rejected reason,
Secure, SameSite, Domain, Path, HTTPS 여부를 확인한다.
- credential 포함 CORS 요청에서
Access-Control-Allow-Origin: *가 안 되는 이유는 무엇인가?
- 브라우저가 인증 정보가 포함된 cross-origin 응답을 임의의 모든 origin에 노출하는 것을 허용하지 않기 때문이다.
- 서버 메모리 세션을 scale out할 때 인프라와 맞춰야 할 것은 무엇인가?
- sticky session을 쓸지, shared session store를 둘지, 배포/장애 시 session 유실을 어떻게 감당할지 정해야 한다.
- CORS preflight가 실패하면 왜 애플리케이션 API가 실행되지 않을 수 있는가?
- 브라우저가 실제 요청 전에
OPTIONS로 허용 여부를 확인하고, preflight 응답이 부적절하면 실제 요청을 보내지 않기 때문이다.