브라우저
쿠키·웹 저장소·인증과 브라우저 보안
브라우저 저장소별 수명과 자동 전송 특성을 구분하고, 모든 인증·인가와 보안 방어를 서버 경계와 함께 설계합니다.
이럴 때 필요해요
로그인과 상태 유지 구현에서 XSS·CSRF 위협과 탭 수명, 서버 권한 검증의 책임을 정확히 분리합니다.
어떻게 동작하나요?
로그인 상태나 사용자 설정을 브라우저에 저장할 때는 각 저장소의 수명과 전송 방식을 먼저 구분해야 합니다. 쿠키는 도메인·경로·만료 조건에 따라 HTTP 요청마다 서버로 자동 전송되며 HttpOnly·Secure·SameSite 속성으로 접근과 전송 범위를 제어할 수 있습니다. 반면 localStorage와 sessionStorage는 JavaScript로만 읽고 쓰며 서버로 자동 전송되지 않습니다. 특히 sessionStorage는 '출처 + 개별 탭'의 페이지 세션에 묶여 있어 같은 탭 안의 새로고침에서는 유지되지만 탭을 닫으면 사라지고 다른 탭과는 공유되지 않습니다.
인증 설계에서 서버 세션 방식은 브라우저 쿠키에 예측 불가능한 세션 ID만 넣어 보내고 실제 사용자 상태는 서버 저장소에서 관리합니다. 반면 JWT 같은 토큰 방식은 서명된 토큰을 검증해 신원을 확인하되, 일반 서명 JWT의 내용은 암호화된 것이 아니라 누구나 디코딩해 볼 수 있으므로 민감 정보를 담지 않습니다. 또한 사용자가 누구인지 확인하는 '인증(Authentication)'과 특정 자원에 접근할 권한이 있는지 확인하는 '인가(Authorization)'는 별개이므로, 프론트엔드에서 버튼을 숨겼더라도 서버 API에서 매 요청마다 권한을 다시 검증해야 합니다.
보안 위협에서도 공격자 스크립트가 우리 사이트 문맥에서 실행되는 XSS와, 쿠키 자동 전송을 악용해 원치 않는 요청을 보내게 만드는 CSRF는 원리와 방어선이 다릅니다. 토큰을 HttpOnly 쿠키에 담으면 XSS로 토큰 문자열을 직접 훔쳐 가는 것은 막을 수 있지만, 쿠키 자동 전송으로 인한 CSRF 방어(SameSite, CSRF 토큰, Origin 검증)와 스크립트 실행 자체를 막는 XSS 방어(출력 이스케이프, 안전한 DOM API, CSP)를 반드시 함께 갖춰야 합니다.
코드 예제
동작을 설명하는 읽기 전용 예제입니다.
Set-Cookie: session=opaque-id; Path=/; HttpOnly; Secure; SameSite=Lax설명용 Set-Cookie 응답 헤더입니다. 실제 운영 서비스에서는 HTTPS 환경에서 HttpOnly·Secure·SameSite 속성과 함께 서버 측 세션 만료·회전·로그아웃 무효화 및 CSRF 방어를 함께 구성합니다.
자주 헷갈리는 포인트
- 쿠키에 HttpOnly 속성을 설정했다는 이유만으로 모든 XSS 공격이나 공격자 스크립트의 인증된 요청 호출까지 완전히 차단된다고 단정하지 않습니다.
- 이름이 비슷하다는 이유로 쿠키, 백엔드 서버 세션, 브라우저의 sessionStorage를 같은 저장소로 섞어 설명하지 않습니다.
내 말로 설명해 보기
인증 토큰을 localStorage 대신 HttpOnly 쿠키로 옮기면 어떤 위험이 줄어들고, 반대로 어떤 추가 방어를 함께 챙겨야 하나요?
실전 시나리오에 적용해 보기
함께 읽으면 좋은 개념
관련 면접 질문 5개
쿠키·서버 세션·웹 스토리지(localStorage·sessionStorage)는 어떻게 다른가요?
쿠키는 만료 시간과 도메인·경로 조건에 따라 브라우저가 HTTP 요청마다 서버로 자동 전송하는 작은 데이터이고, 서버 세션은 민감한 상태를 서버 메모리나 DB에 두고 브라우저에는 세션 ID(보통 쿠키)만 건네 연결하는 방식입니다. 반면 localStorage와 sessionStorage는 브라우저에만 저장되고 요청에 자동 전송되지 않는 문자열 저장소입니다. 그중 localStorage는 같은 출처(Origin)에서 브라우저를 닫아도 유지되지만, sessionStorage는 '출처 + 개별 탭(브라우저 컨텍스트)' 단위의 페이지 세션에 묶여 있어 같은 탭 안의 새로고침·이동에서는 유지되다가 탭을 닫으면 삭제됩니다.
꼬리질문과 참고자료 →쿠키와 서버 세션을 이용한 로그인은 어떻게 설계하나요?
사용자가 로그인 정보를 제출하면 서버는 자격을 검증한 뒤 충분히 길고 예측 불가능한 세션 ID를 생성해 서버 저장소(Redis, DB 등)에 사용자 상태와 만료 시간을 기록합니다. 그리고 그 세션 ID만 Set-Cookie 헤더에 담아 내려주되, JavaScript 접근을 막는 HttpOnly, HTTPS 전송만 허용하는 Secure, 교차 출처 전송을 제어하는 SameSite 속성을 함께 설정합니다. 이후 요청에서는 브라우저가 자동 전송한 쿠키의 세션 ID로 서버가 세션을 조회해 인증·인가를 수행하며, 로그인 성공 시 세션 ID 재발급(회전)과 로그아웃 시 서버 측 세션 즉시 파기, CSRF 방어를 함께 적용합니다.
꼬리질문과 참고자료 →토큰 인증과 JWT를 쿠키에 저장할 때의 보안 위험과 대책은 무엇인가요?
JWT 기반 토큰 인증은 서버가 클라이언트에 서명된 토큰을 발급하고, 요청마다 토큰의 서명과 만료 시간(exp)·클레임을 검증해 신원을 확인하는 방식입니다. 이때 기본 서명된 JWT(JWS)의 Payload는 암호화된 것이 아니라 Base64Url로 인코딩된 상태라 누구나 디코딩해 볼 수 있으므로 민감 정보를 넣으면 안 됩니다. 또한 JWT를 쿠키에 저장할 경우 HttpOnly 속성으로 XSS를 통한 토큰 문자열 직접 탈취는 막을 수 있지만, 쿠키의 자동 전송 특성 때문에 CSRF 공격에 노출될 수 있으므로 SameSite 설정과 CSRF 토큰·Origin 검증, 짧은 Access Token 수명과 토큰 회전·폐기 정책을 함께 설계해야 합니다.
꼬리질문과 참고자료 →