JWT Access Token 저장 위치

김키핑·2026년 9월 3일
post-thumbnail

이걸 왜 고민해야하나

JWT 토큰의 장점은 무상태 방식으로 동작하기 때문에 이전 요청의 상태나 다른 데이터를 참조하지 않고 독립적으로 처리한다는 점이다. JWT를 이용하면 로그인 시 세션 불일치 문제를 걱정하거나 별도의 외부 저장소를 만들 필요가 없어진다.

하지만, JWT는 토큰 탈취에 취약하다.
공격자는 토큰이 만료될 때까지 정상 사용자처럼 서비스에 요청을 보낼 것인데,
사용자가 로그아웃하거나 관리자가 계정을 비활성화해도, 이미 발급된 Access Token이 만료되기 전까지는 계속 사용할 수 있다.

이를 해결하기 위해 클라이언트는 여러 방법을 모색할 수 있는데, 바로


Access Token의 저장

서버

Access Token은 서버측에서 관리할 수 있다.
그치만 오늘의 주제는 프론트엔드 관점이므로, 자세히 살펴보지 않는다.

인메모리 (In-Memory)

가장 단순한 방법. Access Token을 그냥 자바스크립트 변수(또는 React state/context)에 담아두는 것이다.

const [accessToken, setAccessToken] = useState(null);

장점

  • XSS 공격에 가장 안전: 브라우저 저장소(Storage)나 쿠키에 기록되지 않고 메모리 상에만 존재하므로, 스크립트를 통한 토큰 스크래핑(Direct Extraction)을 방지할 수 있다.
  • 구현이 간단함: 별도의 브라우저 API 설정 없이 앱 내부 상태로 손쉽게 관리 가능하다.

단점

  • 휘발성(Persistence 부족): 페이지를 새로고침(F5)하거나 탭을 닫으면 메모리가 초기화되어 토큰이 사라진다.
  • Silent Refresh 필수: 로그인 상태를 유지하려면 httpOnly 쿠키에 저장된 Refresh Token을 이용해 새로고침 시마다 토큰을 재발급받는 로직이 반드시 수반되어야 한다.

서버가 Set-Cookie 헤더를 통해 브라우저 쿠키에 토큰을 저장하도록 지시하는 방식이다.

장점

  • HttpOnly 설정 시 XSS 방어: JavaScript(document.cookie)를 통한 접근이 차단되어 악성 스크립트로 토큰을 탈취할 수 없다.
  • 자동 전송의 편리함: 설정된 도메인으로 요청을 보낼 때 브라우저가 쿠키를 자동으로 첨부한다.

단점

  • CSRF 공격에 취약: 자동 전송 특성 때문에 타 사이트에서의 요청에 악용될 수 있으므로, 보안 옵션 설정이 필수적이다.
속성방어 대상 및 역할
HttpOnlyXSS 방어: JavaScript 접근 차단
Secure중간자 공격(MITM) 방어: HTTPS 암호화 통신 채널에서만 전송 허용
SameSite=Strict / LaxCSRF 방어: 타 사이트에서의 교차 요청 제어 (Strict: 전면 차단, Lax: GET 등 안전한 탐색 시 일부 허용)

SessionStorage

웹 스토리지 API 중 하나로, 브라우저의 탭(세션) 단위로 독립된 저장 공간을 제공한다.

장점

  • 같은 도메인이라도 탭 간 데이터가 공유되지 않아 독립된 단기 세션 데이터 관리에 유용하며, 탭을 닫으면 데이터가 자동 삭제된다.

단점

  • localStorage와 동일하게 JavaScript로 자유롭게 접근 가능하여 XSS 공격에 완전히 노출된다. (sessionStorage.getItem()으로 쉽게 추출 가능)
  • 탈취 위험이 크므로 Access Token이나 Refresh Token 등 민감한 인증 데이터 저장소로는 적합하지 않다.

LocalStorage

브라우저를 닫거나 컴퓨터를 재부팅해도 데이터가 영구적으로 유지되는 키-값(Key-Value) 저장소이다.

장점

  • 탭과 세션을 넘어 로그인 상태가 계속 유지되며, 서버 통신 없이 즉시 조회 가능하여 구현이 매우 직관적이다.

단점

  • XSS(Cross-Site Scripting) 공격에 무방비 상태로 노출된다.
  • 악성 스크립트가 삽입되는 순간 localStorage.getItem()을 통해 토큰이 통째로 탈취될 수 있어, 인증 토큰 저장소로는 보안상 치명적이다.

서버 vs 프론트

Access Token은 저장 주체에 따라 관리 방식과 트레이드오프(:하나를 얻기 위해 다른 하나를 어느 정도 포기해야 하는 관계) 가 완전히 달라진다.

서버는 "토큰을 저장하지 않아도" 되는 게 JWT의 원래 장점이고, 프론트는 "저장을 안 할 수가 없다"는 게 차이다. 서버가 저장한다면 그건 주로 강제 무효화(로그아웃, 탈취 대응)를 위한 선택적 조치이고, 프론트가 저장하는 이유는 매 요청마다 인증 정보를 실어 보내야 하기 때문에 필수적인 것이다.

구분서버프론트엔드
저장 위치Redis, DB 등 (선택적, 필수는 아님)브라우저 (인메모리 / 쿠키 / Storage)
저장 목적무효화(블랙리스트), 세션 통제매 요청마다 인증 헤더에 실어 보내기 위함
JWT의 무상태성 유지 여부저장 안 하면 무상태 유지, 저장하면 사실상 세션 방식과 유사해짐저장 여부와 무관하게 무상태성 유지
주요 위협서버 침해 시 전체 토큰 노출 가능 (DB/Redis 해킹)XSS(스크립트 탈취), CSRF(자동 전송 악용)
통제권강함 — 즉시 무효화, 강제 로그아웃 가능약함 — 만료 전까지 서버가 개입 불가
확장성 영향저장할 경우 매 요청마다 조회 필요 → 병목 가능클라이언트 로컬 처리라 서버 부하 없음
profile
양치기소녀

0개의 댓글