JWT 토큰 인증 개념 및 회원 플랫폼 프로젝트 분석

MSA 환경에서 여러 서비스가 공통으로 사용하는 회원 관리 플랫폼 API 프로젝트를 분석하였습니다.


JWT 토큰 인증 분석

세션 대신 JWT 사용 이유

세션 인증 방식은 상태를 서버에 저장하므로 세션 저장소에 의존성이 발생하지만,
JWT는 인증 정보를 토큰에 담아 전달해서 각 서비스가 독립적으로 검증하는 방식도 가능합니다.

모바일 앱 등 다양한 클라이언트 환경에서도 인증이 용이하고 확장성이 좋습니다.

대규모 트래픽 환경에서는 서버에 인증 상태를 보관하는 세션 방식보다
인증 정보를 토큰 형태로 전달하는 JWT 방식이 서버 메모리 부담을 줄일 수 있습니다.
매 요청마다 토큰을 파싱하고 서명을 검증하는 CPU 연산 비용은 추가됩니다.

토큰 만료 시간 설정 근거

액세스 토큰 만료 시간 : 15분
액세스 토큰은 탈취 즉시 API 호출하여 악용될 수 있기 때문에 만료 시간이 짧을수록 안전합니다.
하지만 액세스 토큰 만료가 빈번해 자주 재발급하면 네트워크 트래픽이 증가하고 UX 저하가 발생합니다.
네트워크가 느린 환경에서도 사용자 경험을 해치지 않고 보안을 강화하도록 15분으로 설정했습니다.

15분은 OWASP JWT Sheet 권장 하한값이며, 탈취 시 피해를 최소화할 수 있습니다.
더 짧은 만료시간보다 토큰 재사용 감지가 보안 강화에 더 효과적입니다.

리프레시 토큰 만료 시간 : 7일
리프레시 토큰 만료 시간이 길면 재로그인을 최소화해서 사용자 경험이 향상되지만,
탈취 시 장기간 악용될 수 있다는 점을 고려해서 7일로 설정하였습니다.

Rotation 적용 시, 액티브 유저는 슬라이딩 세션 효과를 제공받아 7일 제한이 체감되지 않게 됩니다.

Refresh Token Rotation 적용

클라이언트가 리프레시 토큰을 이용해서 액세스 토큰을 재발급 요청하면,
액세스 토큰 및 리프레시 토큰을 모두 새로 발급합니다.

리프레시 토큰 재발급 시, 기존 리프레시 토큰을 무효화하고 새로 발급하는 방식을 적용합니다.

기존 토큰을 서버에서 관리할 경우, 탈취된 토큰의 재사용을 탐지하거나 차단할 수 있습니다.
토큰 재사용이 감지되면 레디스에서 해당 회원의 전체 세션을 무효화하고
사용자에게 안내해서 모든 기기 재로그인을 유도하는 것이 보안상 안전합니다.

JWT 토큰 저장 장소 선정

액세스 토큰 : 메모리
로컬스토리지에 저장하면 Javascript를 이용한 XSS 공격으로 토큰이 탈취될 수 있으므로,
JavaScript 변수 (메모리) 에 저장하는 것이 권장됩니다.
페이지를 새로고침하면 토큰이 휘발되므로 리프레시 토큰으로 받아오는 처리가 필요합니다.

리프레시 토큰 : HttpOnly 쿠키
HttpOnly 쿠키에 저장하면 Javascript로 접근할 수 없어 안전하고,
HTTP 요청 시마다 쿠키가 헤더에 자동 포함되어 전송되므로 인증 처리가 간편합니다.

토큰을 쿠키에 저장 시, 의도치 않은 요청을 보내는 CSRF 공격에 취약할 수 있으므로
다른 사이트에서 온 요청에는 쿠키를 보내지 않는 SameSite=Strict 설정 방어가 필요합니다.

JWT 인증 관리 레디스 도입 이유

서버가 토큰 상태를 알 수 없는 stateless 방식의 JWT 운영 통제 한계를 보완하기 위해서
레디스에 리프레시 토큰, 세션 목록, Rate Limit, 로그인 실패 횟수 등을 저장하고 관리했습니다.

레디스 장점

  • 데이터를 디스크가 아니라 메모리에 저장하여 일반 DB보다 처리 속도가 훨씬 빠름
  • 여러 클라이언트가 동시 실행해도 값이 꼬이지 않는 원자적 연산 (INCR key)를 제공
  • 저장된 key마다 EXPIRE 명령으로 유효기간 (TTL) 설정하여 자동 만료 가능

DB 설계 및 보안 분석

###