Skip to content
난이도 면접 빈출문제은행 4

HTTP의 응용 ​

HTTP는 요청 사이를 기억하지 않는 단순한 규칙이라, 실제 웹 서비스는 그 위에 여러 장치를 얹어 쓴다. 이 문서는 그중 로그인 상태를 요청 사이에 잇는 두 방식, 즉 정보를 서버에 두는 방식과 서명한 토큰(token)에 담는 방식을 비교한다. 같은 응답을 다시 받지 않게 저장해 두는 캐시(cache)도 함께 다룬다.

쿠키와 세션: 무상태를 보완하기 ​

HTTP는 무상태(stateless) 프로토콜(protocol)이라 서버는 방금 로그인한 사람이 다음 요청을 보내도 같은 사람인지 모른다. 이를 보완하는 기본 도구가 쿠키(cookie)다. 쿠키는 서버가 응답의 Set-Cookie 헤더(header)로 브라우저에 저장시키고, 브라우저가 이후 같은 사이트로 가는 요청마다 Cookie 헤더에 자동으로 실어 보내는 작은 데이터다.

http
Set-Cookie: sid=a3f9...; HttpOnly; Secure; SameSite=Lax; Max-Age=3600

쿠키에 붙이는 속성은 보안에 직접 영향을 준다.

  • HttpOnly: 자바스크립트의 document.cookie로 읽을 수 없게 한다. 페이지에 악성 스크립트가 끼어들어도 쿠키를 훔쳐 가기 어려워진다.
  • Secure: HTTPS(HTTP Secure, 보안 HTTP) 연결에서만 쿠키를 보낸다. 암호화되지 않은 연결에서 쿠키가 노출되는 것을 막는다.
  • SameSite: 다른 사이트에서 시작된 요청에 쿠키를 실을지 정한다. Strict는 싣지 않고, Lax는 링크를 눌러 이동하는 정도만 허용하며, None은 항상 싣는다(Secure 필수). 쿠키가 무조건 실리면 악성 사이트가 사용자 모르게 로그인된 상태로 요청을 보내게 만들 수 있어서다. 이런 공격을 CSRF(Cross-Site Request Forgery, 사이트 간 요청 위조)라고 한다. 일부 브라우저는 지정이 없으면 Lax로 다룬다.

세션(session) 방식은 로그인 정보 자체를 서버 쪽 저장소에 두고, 브라우저에는 그 정보를 찾을 열쇠인 세션 ID만 쿠키로 준다. 사용자 정보가 브라우저로 나가지 않고, 서버가 저장소에서 지우기만 하면 로그아웃이나 강제 만료가 즉시 된다. 대신 서버를 여러 대로 늘리면 어느 서버로 요청이 가도 같은 세션을 찾을 수 있게 저장소를 공유해야 한다.

토큰과 JWT ​

토큰 방식은 서버가 로그인 성공 시 "이 사용자는 누구이고 언제까지 유효하다"는 정보를 담은 토큰을 발급하고, 클라이언트가 요청마다 Authorization: Bearer <토큰> 헤더로 보내는 방식이다. 대표 형식이 JWT(JSON Web Token, JSON 웹 토큰)다.

JWT는 점으로 이은 세 부분, 헤더·페이로드(payload)·서명(signature)으로 이뤄진다. 페이로드에는 사용자 ID와 만료 시각 같은 정보가 들어가고, 서명은 서버가 가진 키로 만든다. HS256처럼 비밀 키 하나로 서명과 검증을 함께 하는 방식도 있고, RS256처럼 개인 키로 서명하고 짝이 되는 공개 키로 검증하는 방식도 있다. 서버는 서명만 검증하면 토큰이 위조되지 않았음을 알 수 있으므로 세션 저장소를 조회할 필요가 없다.

기준세션JWT
상태 저장서버 저장소에 둔다토큰 안에 담는다
서버 확장저장소 공유가 필요하다서명 키만 공유하면 된다
즉시 폐기저장소에서 지우면 된다만료 전에는 어렵다
크기세션 ID만 오가 작다정보를 담아 크다

JWT의 가장 큰 약점은 폐기다. 토큰이 유출돼도 서버가 기억하는 상태가 없으니 만료 시각까지는 유효하다. 그래서 보통 수명이 짧은 액세스 토큰(access token)과, 새 액세스 토큰을 받는 데만 쓰는 긴 수명의 리프레시 토큰(refresh token)을 함께 쓴다. 액세스 토큰은 유출돼도 금방 만료되므로 피해 기간이 짧고, 리프레시 토큰은 보통 서버가 따로 기록해 두므로 필요할 때 서버에서 무효화할 수 있다. 또 페이로드는 암호화가 아니라 Base64URL이라는 규칙으로 글자만 바꿔 적은 인코딩일 뿐이다. 열쇠 없이 누구나 원래 JSON으로 되돌려 읽을 수 있으므로, 비밀번호 같은 민감 정보를 넣으면 안 된다.

HTTP 캐시 ​

HTTP 캐시는 한 번 받은 응답을 브라우저나 중간 서버에 저장해 두고 같은 요청에 다시 쓰는 기능이다. 네트워크 왕복과 서버 부하가 줄어 페이지가 빨라진다. 저장해도 되는지, 얼마나 오래 쓸 수 있는지는 서버가 응답의 Cache-Control 헤더로 알린다.

  • max-age=3600: 받은 뒤 3600초 동안은 서버에 묻지 않고 저장본을 그대로 쓴다.
  • no-cache: 저장은 해도 되지만, 쓰기 전에 매번 서버에 "아직 유효한지" 확인해야 한다. 이름과 달리 캐시 금지가 아니다.
  • no-store: 아예 저장하지 않는다. 개인 정보가 담긴 응답에 쓴다.

유효 기간이 지난 저장본은 버리지 않고 재검증(revalidation)한다. 서버는 처음 응답에 내용의 지문 격인 ETag 값을 붙여 주고, 브라우저는 다음 요청에 If-None-Match: <그 값>을 보낸다. 내용이 바뀌지 않았다면 서버는 본문 없이 304 Not Modified만 돌려주고, 브라우저는 저장본을 계속 쓴다. 본문을 다시 받지 않으니 큰 파일일수록 이득이 크다.

이어지는 내용은 HTTP의 응용 2에서 다룬다. 다른 출처의 응답을 읽는 규칙과 HTTP/1.1·HTTP/2·HTTP/3의 차이를 본다.

면접 포인트 ​

  • "쿠키와 세션 차이는?" → 쿠키는 브라우저 저장·자동 전송, 세션은 서버 저장 + 쿠키엔 세션 ID만.
  • "세션 대신 JWT를 쓰는 이유와 단점은?" → 서버 저장소 없이 서명 검증만으로 확장 쉬움. 대신 만료 전 폐기 어려움, 페이로드는 암호화 아님.
  • "no-cache와 no-store 차이는?" → no-cache는 저장하되 매번 재검증, no-store는 저장 금지.

관련 문서