Foundry
보안
중급
핵심

JWT 저장 위치와 리프레시 토큰

토큰을 어디에 두고 언제 만료시킬 것인가

JWT 저장 위치와 리프레시 토큰

저장 위치 트레이드오프

위치XSSCSRF비고
localStorage취약(스크립트 접근 가능)안전구현 간단
HttpOnly 쿠키안전취약 -> SameSite, 토큰 병행서버 설정 필요
메모리 변수상대적으로 안전안전새로고침 시 소실

단일 정답은 없다. 쿠키 + SameSite + CSRF 방어 조합이 일반적인 기본값이다.

만료와 갱신

Access Token   짧게(분 단위)  -> 탈취 시 유효 시간 제한
Refresh Token  길게(일 단위)  -> HttpOnly 쿠키, 재발급 경로 전용
  • 회전: 재발급마다 새 리프레시 토큰을 주고 기존 토큰을 폐기한다
  • 재사용 감지: 폐기된 리프레시 토큰이 다시 오면 해당 세션 전체를 무효화한다

실무 포인트

  • JWT는 서명이지 암호화가 아니다. 페이로드는 누구나 디코드하므로 민감정보를 넣지 않는다
  • 자체 포함 토큰은 즉시 폐기가 어렵다. 짧은 만료 + 서버측 차단 목록(jti)으로 보완
  • 검증 알고리즘을 서버에서 고정한다. 토큰의 alg를 그대로 신뢰하면 우회 여지가 생긴다
  • 로그아웃은 클라이언트 삭제로 끝나지 않는다. 리프레시 토큰 폐기가 실제 로그아웃이다
면접에서 이렇게 나옵니다

Q.액세스 토큰을 localStorage에 저장하는 구현의 위험과 대안을 설명해주세요

XSS 한 번에 토큰이 전부 새어 나갑니다. 스크립트가 자유롭게 읽을 수 있기 때문입니다.

저장 위치XSS 로 읽힘CSRF 위험비고
localStorage읽힌다낮다가장 취약
메모리(변수)실행 중에는 접근 가능낮다새로고침에 사라진다
httpOnly 쿠키읽히지 않는다있다. 방어 필요권장 조합의 기반

권장 조합은 이렇습니다.

토큰어디에 두나
리프레시 토큰httpOnly, Secure, SameSite 쿠키
액세스 토큰메모리에 두고 짧게 유지한다 (15분 안팎)
새로고침 시쿠키로 조용히 재발급받는다

이렇게 하면 XSS 로 액세스 토큰이 새더라도 유효 기간이 짧고, 리프레시 토큰은 스크립트가 읽을 수 없습니다.

흔한 실수: httpOnly 쿠키로 옮기면 끝이라고 답하는 것. 쿠키는 CSRF 표면이 생기므로 SameSite 와 토큰 검증이 함께 가야 합니다.

Q.이미 발급된 JWT를 즉시 무효화해야 한다면 어떻게 하겠습니까?

무상태 토큰은 서버가 기억하지 않으므로, 무효화하려면 어딘가에 상태를 두는 대가를 내야 합니다.

방법내용대가
수명을 짧게15분 안팎으로 두고 갱신으로 처리그 시간 동안은 통한다
차단 목록무효화한 토큰 id 를 저장소에 담아 검증마다 조회무상태의 이점을 일부 포기
발급 시각 기준사용자별 최소 발급 시각을 두고 그보다 이전 토큰 거부사용자 단위 조회 필요
토큰 버전사용자 레코드의 버전을 토큰에 넣고 비교사용자 조회 필요. 전체 무효화가 쉽다

즉시성이 꼭 필요하다면(계정 정지, 비밀번호 변경) 차단 목록이나 버전 방식을 씁니다. 조회 비용은 캐시로 줄일 수 있습니다.

흔한 실수: 무상태와 즉시 무효화를 함께 가질 수 있다고 답하는 것. 둘은 맞바꾸는 관계이고, 어느 쪽을 얼마나 포기할지 정하는 것이 설계입니다.

Q.리프레시 토큰 회전과 재사용 감지는 어떤 공격을 막나요?

탈취된 리프레시 토큰의 장기 사용을 막습니다.

장치동작
회전갱신할 때마다 새 리프레시 토큰을 주고 옛것을 폐기한다
감지이미 폐기된 토큰이 다시 오면 탈취로 보고 그 계열 전체를 무효화한다

공격자가 리프레시 토큰을 훔쳤다고 해봅시다.

누가 먼저 쓰나결과
공격자가 먼저정상 사용자의 옛 토큰이 폐기된 것으로 감지되어 전체 무효화
사용자가 먼저공격자의 토큰이 폐기된 것으로 감지되어 전체 무효화

어느 쪽이든 재사용이 드러나는 순간 계열 전체가 끊깁니다. 회전만 있고 감지가 없으면 공격자가 계속 갱신해 무한히 쓸 수 있습니다.

흔한 실수: 회전만 도입하고 감지를 빼는 것. 그러면 탈취를 알아챌 방법이 없습니다. 그리고 네트워크 재시도로 같은 토큰이 두 번 올 수 있어, 짧은 유예 창을 두지 않으면 정상 사용자가 로그아웃됩니다.

Q.액세스 토큰 만료 시간을 정하는 기준은 무엇인가요?

탈취 피해 시간갱신 부담 사이에서 정합니다.

만료 시간탈취 시 노출갱신 호출
5분짧다잦다. 인증 서버 부하
15분에서 30분흔한 절충적당하다
24시간하루 종일 통한다거의 없다

판단 재료는 이렇습니다.

판단 재료내용
민감도금융이나 관리자 권한이면 짧게
무효화 수단차단 목록이 있으면 조금 길게 둘 수 있다
클라이언트모바일은 갱신이 백그라운드에서 조용히 된다
호출량초당 수만이면 갱신 부하 자체가 비용이다

액세스 토큰이 짧은 만큼 리프레시 토큰이 길어지므로, 그쪽에 회전과 재사용 감지를 두는 것이 함께 갑니다.

흔한 실수: 사용자 편의를 위해 길게 잡고 무효화 수단을 두지 않는 것. 그러면 계정 정지나 비밀번호 변경이 만료 시간까지 효력이 없습니다.

먼저 스스로 답해보고 아래 답변과 견줘보세요. 막히는 부분은 문제로 확인할 수 있어요.

읽었으면 문제로 확인해보세요

보안 문제를 풀면 틀린 문제가 자동으로 노트에 쌓입니다. 가입 없이 5문제를 먼저 풀어볼 수도 있어요.