세션 쿠키는 전통적인 웹 로그인 방식으로, 로그인 성공 시 서버가 임의의 세션 ID를 발급해 `Set-Cookie`로 내려주고, 브라우저가 이후 모든 요청에 `Cookie` 헤더로 자동 전송합니다. 실제 사용자 상태(로그인 정보·권한)는 서버 측 세션 저장소에 두고, 쿠키에는 그 저장소를 가리키는 식별자만 담는 것이 정석입니다.
Set-Cookie: sessionid=...; HttpOnly; Secure; SameSite=Lax on login → Cookie: sessionid=... on each request흐름은 이렇습니다. 사용자가 자격 증명으로 로그인하면 서버가 세션을 만들어 저장소(메모리·Redis·DB)에 넣고, 그 세션 ID를 쿠키로 보냅니다. 브라우저는 같은 도메인 요청마다 쿠키를 자동으로 붙이므로 클라이언트 코드가 토큰을 직접 관리할 필요가 없습니다. 로그아웃·강제 만료는 서버가 저장소에서 세션을 지우면 즉시 반영되는데, 이는 무상태 JWT가 갖기 어려운 폐기(revocation)의 장점입니다.
쿠키의 보안은 속성으로 결정됩니다. HttpOnly는 자바스크립트의 `document.cookie` 접근을 막아 XSS로 인한 세션 탈취를 줄이고, Secure는 HTTPS에서만 전송하게 하며, SameSite(Lax/Strict/None)는 다른 사이트에서 온 요청에 쿠키를 붙일지를 제어해 CSRF를 크게 완화합니다. Path·Domain·Max-Age/Expires로 범위와 수명을 제한합니다.
쿠키가 자동 전송된다는 편리함은 곧 CSRF(교차 사이트 요청 위조)의 근본 원인입니다. 공격자 사이트가 사용자의 브라우저로 우리 서버에 요청을 보내면 브라우저가 세션 쿠키를 자동으로 실어 보내기 때문입니다. 그래서 SameSite 설정과 더불어 CSRF 토큰(요청에 별도 검증값 요구) 같은 방어를 함께 씁니다.
Set-Cookie: sessionid=f3a1c9e2b7d84; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600HTTP/1.1 200 OK
Set-Cookie: sessionid=f3a1c9e2b7d84; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600fetch('/api/me', {
credentials: 'include' // sends the session cookie cross-site
});sid = request.cookies.get('sessionid')
session = store.get(sid) # server-side session store
if not session or session.expired:
return Response(status=401)
user = session.user