[BE] JWT 토큰을 알아보자

Kwanni·2025년 7월 4일
0

BackEnd

목록 보기
4/4

들어가며

스프링부트를 공부하면서 인증과 인가에 대해 실습을 진행하면서 처음에는 단순히 로그인 기능만 구현하면 된다고 생각했지만 인증 정보를 어떻게 안전하게, 그리고 효율적으로 관리할지에 대해 의문이 생겼다.
특히 HTTP가 본질적으로 stateless(상태를 저장하지 않는) 프로토콜이라는 점 때문에, 사용자가 한 번 로그인했다고 해서 그 상태가 계속 유지되는 것이 아니라는 사실을 알게 되었다. 이로 인해 쿠키, 세션, 토큰 등 다양한 인증 방식이 등장했고, 그 중에서도 JWT(Json Web Token)에 대해 더 알아보고 싶었다.

이번 글에서는 기존 인증 방식의 한계, 그리고 JWT가 제공하는 장점과 주의할 점까지 정리해보려고 한다. 이 과정을 통해 단순히 JWT의 사용법만이 아니라, 왜 JWT가 필요한지에 대한 본질적인 이유를 스스로 이해하고자 한다.

JWT란 무엇인가?

JWTJSON Web Token의 약자로, 웹 표준(RFC 7519)에 정의된 토큰 기반 인증 방식이다.
서버와 클라이언트가 정보를 주고받을 때, 인증 및 권한 정보를 토큰 자체에 담아 안전하게 전달하는 방법이다.

기존 세션 방식과 달리, JWT는 서버가 별도의 상태를 저장하지 않아도 되기 때문에 stateless(무상태) 인증이 가능하다는 장점이 있다.

JWT의 구조

JWT는 세 부분으로 구성되어 있으며, 각각은 점(.)으로 구분된다.

구성요소설명
헤더(Header)토큰 타입(JWT)과 서명에 사용할 알고리즘 정보 포함
페이로드(Payload)사용자 정보와 권한 등 실제 데이터(클레임)를 담는 부분
서명(Signature)헤더와 페이로드를 합쳐 비밀키로 서명한 무결성 검증용 데이터

1. 헤더(Header)

헤더에는 토큰 타입과 서명 알고리즘 정보가 들어간다.

{
  "alg": "HS256",
  "typ": "JWT"
}
  • typ: 토큰의 타입을 명시한다. JWT에서는 "JWT"로 고정한다.
  • alg: 서명(Signature)을 생성할 때 사용할 알고리즘을 지정한다. 여기서는 "HS256"이 사용된다.

HS256 알고리즘을 왜 사용하는지에 대해 간단하게 알아봤다.

HS256이란?

  • HS256은 HMAC-SHA256(Hash-based Message Authentication Code with SHA-256) 알고리즘을 의미한다.
  • HMAC은 대칭키(하나의 비밀키) 기반의 서명 방식으로, 같은 키로 서명 생성과 검증을 모두 수행한다.
  • SHA-256은 널리 검증된 해시 함수로, 보안성과 성능이 모두 우수하다.

HS256을 사용하는 이유

  • 구현이 간단하고 빠르다: 대칭키 방식이기 때문에 공개키/개인키를 따로 관리할 필요가 없고, 연산 속도가 빠르다.
  • 서버 간 신뢰 관계에서 적합: 서버가 하나이거나, 신뢰할 수 있는 서버들끼리만 토큰을 발급·검증할 때 적합하다. 같은 비밀키만 공유하면 되기 때문이다.
  • 무결성 보장: 토큰이 발급된 이후 내용이 변조되면 서명 검증에 실패하므로, 데이터의 무결성을 보장할 수 있다.
  • 라이브러리 지원이 풍부하다: 다양한 언어와 프레임워크에서 기본적으로 지원한다.

2. 페이로드(Payload)

페이로드에는 인증에 필요한 정보, 즉 클레임(Claim)들이 담긴다.
클레임은 키-값 쌍으로, 주로 사용자 ID, 권한, 만료시간 등만 포함하는 것이 좋다.

{
  "sub": "1234567890",
  "name": "홍길동",
  "admin": true,
  "iat": 1516239022
}

3. 서명(Signature)

서명은 헤더와 페이로드를 인코딩한 후, 서버가 가진 비밀키로 해싱하여 만든다.
이 서명을 통해 토큰이 위·변조되지 않았는지 검증할 수 있다.

JWT의 동작 원리

  1. 사용자가 로그인 정보를 서버에 보낸다.
  2. 서버는 사용자 인증 후, 사용자 정보를 페이로드에 담아 JWT 토큰을 생성한다.
  3. 이 토큰을 클라이언트에 전달한다.
  4. 클라이언트는 이후 요청 시 JWT 토큰을 HTTP 헤더(Authorization)에 담아 서버에 보낸다.
  5. 서버는 토큰의 서명을 검증하고, 페이로드의 정보를 확인해 인증 여부를 판단한다.
  6. 인증이 확인되면 요청한 자원에 접근을 허용한다.

JWT의 장점과 주의사항

장점

  • 서버에 세션 저장소가 필요 없어 확장성이 좋다
  • 토큰 자체에 인증 정보가 포함되어 별도 DB 조회가 불필요하다
  • HTTP 헤더에 담아 전송 가능해 REST API와 잘 어울린다

주의사항

  • 페이로드는 인코딩만 되어 있고 암호화되지 않았으므로, 민감한 정보는 절대 담지 말아야 한다
  • 토큰 탈취 시 악용 위험이 있으니, 반드시 만료시간을 설정하고 HTTPS를 사용해야 한다
  • 비밀키 관리를 철저히 하고, 주기적으로 키를 교체하는 것이 좋다

JWT 체크포인트

1. 페이로드 변조 위험

JWT의 페이로드는 누구나 볼 수 있으니, 민감한 정보(주민등록번호, 비밀번호 등)는 절대 담지 않아야 한다.
실제로 페이로드 값만 바꿔서 API를 호출하면 다른 사용자의 정보에 접근되는 취약점이 발견된 사례도 있다.

2. 로그아웃 처리의 어려움

JWT는 서버가 상태를 저장하지 않는 구조라 로그아웃 처리가 까다롭다.

  • 토큰 만료 시간을 짧게 설정하거나,
  • 서버에서 블랙리스트(무효 토큰 목록)를 관리하는 방식으로 보완할 수 있다.

3. 토큰 탈취 시 대처 방안

JWT가 노출되면 누구나 해당 사용자인 척할 수 있다.

  • 반드시 HTTPS를 사용
  • 토큰 저장 위치는 로컬스토리지보다는 HttpOnly 쿠키를 권장한다.

4. 토큰 갱신(Refresh Token) 전략

Access Token과 Refresh Token을 분리해서 관리하는 것이 일반적이다.

  • Access Token은 짧은 유효기간, Refresh Token은 더 긴 유효기간을 부여한다.
  • Refresh Token도 탈취 위험이 있으므로 별도의 저장소(DB)나 블랙리스트를 활용해야 한다.

5. 토큰 크기와 클레임 관리

불필요한 정보를 많이 담으면 토큰 크기가 커져 네트워크 비용이 증가한다. 꼭 필요한 정보만 클레임에 포함시키는 것이 좋다.

쿠키, 세션, JWT(토큰) 비교

마지막으로 쿠키, 세션, 토큰 인증방식을 비교해보았다.

구분쿠키(Cookie)세션(Session)JWT(토큰)
저장 위치클라이언트(브라우저)서버클라이언트(주로 브라우저, 앱 등)
인증 정보쿠키에 직접 저장(민감 정보 저장 주의)세션 ID만 쿠키에 저장, 실제 정보는 서버에토큰 자체에 인증/권한 정보 포함
상태 관리상태 유지(서버/클라이언트 모두 필요)서버가 세션 상태 관리무상태(Stateless), 서버 상태 저장 불필요
확장성서버 확장 시 세션 동기화 필요서버 확장 시 세션 동기화 필요서버 확장에 유리(상태 저장 불필요)
보안탈취 시 정보 노출 위험, Secure/HttpOnly 옵션 필요세션 ID 탈취 위험, 서버 관리 필요토큰 탈취 시 위험, 만료/HTTPS/비밀키 관리 필요
만료 관리만료일 직접 지정세션 타임아웃 설정토큰에 만료(exp) 직접 포함
사용 예시간단한 로그인 유지, 사용자 설정전통적인 웹 로그인, 쇼핑몰 등REST API, SPA, 모바일 앱, 마이크로서비스

쿠키, 세션 방식은 서버에 상태를 저장해야 하므로, 서버 확장성, 무상태 아키텍처등에서 토큰 방식에 비해 불리하다.

마치며

이 글을 통해 JWT의 기본 개념부터 실제로 사용할 때 주의해야 할 점, 그리고 기존 인증 방식과의 차이까지 정리해보았다. 2달정도 스프링부트-핵심가이드 도서를 통해 이론과 간단한 실습을 통해 백엔드를 학습했다. 앞으로 간단한 시스템을 구현해보고 프로젝트를 통해 스프링부트에 대해 한층 더 알아볼 예정이다.

참고자료

profile
Success is not an accident, Success is actually a choice.

0개의 댓글