스프링부트를 공부하면서 인증과 인가에 대해 실습을 진행하면서 처음에는 단순히 로그인 기능만 구현하면 된다고 생각했지만 인증 정보를 어떻게 안전하게, 그리고 효율적으로 관리할지에 대해 의문이 생겼다.
특히 HTTP가 본질적으로 stateless(상태를 저장하지 않는) 프로토콜이라는 점 때문에, 사용자가 한 번 로그인했다고 해서 그 상태가 계속 유지되는 것이 아니라는 사실을 알게 되었다. 이로 인해 쿠키, 세션, 토큰 등 다양한 인증 방식이 등장했고, 그 중에서도 JWT(Json Web Token)에 대해 더 알아보고 싶었다.
이번 글에서는 기존 인증 방식의 한계, 그리고 JWT가 제공하는 장점과 주의할 점까지 정리해보려고 한다. 이 과정을 통해 단순히 JWT의 사용법만이 아니라, 왜 JWT가 필요한지에 대한 본질적인 이유를 스스로 이해하고자 한다.
JWT는 JSON Web Token의 약자로, 웹 표준(RFC 7519)에 정의된 토큰 기반 인증 방식이다.
서버와 클라이언트가 정보를 주고받을 때, 인증 및 권한 정보를 토큰 자체에 담아 안전하게 전달하는 방법이다.
기존 세션 방식과 달리, JWT는 서버가 별도의 상태를 저장하지 않아도 되기 때문에 stateless(무상태) 인증이 가능하다는 장점이 있다.
JWT는 세 부분으로 구성되어 있으며, 각각은 점(.
)으로 구분된다.
구성요소 | 설명 |
---|---|
헤더(Header) | 토큰 타입(JWT)과 서명에 사용할 알고리즘 정보 포함 |
페이로드(Payload) | 사용자 정보와 권한 등 실제 데이터(클레임)를 담는 부분 |
서명(Signature) | 헤더와 페이로드를 합쳐 비밀키로 서명한 무결성 검증용 데이터 |
헤더에는 토큰 타입과 서명 알고리즘 정보가 들어간다.
{
"alg": "HS256",
"typ": "JWT"
}
"JWT"
로 고정한다."HS256"
이 사용된다. HS256 알고리즘을 왜 사용하는지에 대해 간단하게 알아봤다.
페이로드에는 인증에 필요한 정보, 즉 클레임(Claim)들이 담긴다.
클레임은 키-값 쌍으로, 주로 사용자 ID, 권한, 만료시간 등만 포함하는 것이 좋다.
{
"sub": "1234567890",
"name": "홍길동",
"admin": true,
"iat": 1516239022
}
서명은 헤더와 페이로드를 인코딩한 후, 서버가 가진 비밀키로 해싱하여 만든다.
이 서명을 통해 토큰이 위·변조되지 않았는지 검증할 수 있다.
JWT의 페이로드는 누구나 볼 수 있으니, 민감한 정보(주민등록번호, 비밀번호 등)는 절대 담지 않아야 한다.
실제로 페이로드 값만 바꿔서 API를 호출하면 다른 사용자의 정보에 접근되는 취약점이 발견된 사례도 있다.
JWT는 서버가 상태를 저장하지 않는 구조라 로그아웃 처리가 까다롭다.
JWT가 노출되면 누구나 해당 사용자인 척할 수 있다.
Access Token과 Refresh Token을 분리해서 관리하는 것이 일반적이다.
불필요한 정보를 많이 담으면 토큰 크기가 커져 네트워크 비용이 증가한다. 꼭 필요한 정보만 클레임에 포함시키는 것이 좋다.
마지막으로 쿠키, 세션, 토큰 인증방식을 비교해보았다.
구분 | 쿠키(Cookie) | 세션(Session) | JWT(토큰) |
---|---|---|---|
저장 위치 | 클라이언트(브라우저) | 서버 | 클라이언트(주로 브라우저, 앱 등) |
인증 정보 | 쿠키에 직접 저장(민감 정보 저장 주의) | 세션 ID만 쿠키에 저장, 실제 정보는 서버에 | 토큰 자체에 인증/권한 정보 포함 |
상태 관리 | 상태 유지(서버/클라이언트 모두 필요) | 서버가 세션 상태 관리 | 무상태(Stateless), 서버 상태 저장 불필요 |
확장성 | 서버 확장 시 세션 동기화 필요 | 서버 확장 시 세션 동기화 필요 | 서버 확장에 유리(상태 저장 불필요) |
보안 | 탈취 시 정보 노출 위험, Secure/HttpOnly 옵션 필요 | 세션 ID 탈취 위험, 서버 관리 필요 | 토큰 탈취 시 위험, 만료/HTTPS/비밀키 관리 필요 |
만료 관리 | 만료일 직접 지정 | 세션 타임아웃 설정 | 토큰에 만료(exp) 직접 포함 |
사용 예시 | 간단한 로그인 유지, 사용자 설정 | 전통적인 웹 로그인, 쇼핑몰 등 | REST API, SPA, 모바일 앱, 마이크로서비스 |
쿠키, 세션 방식은 서버에 상태를 저장해야 하므로, 서버 확장성, 무상태 아키텍처등에서 토큰 방식에 비해 불리하다.
이 글을 통해 JWT의 기본 개념부터 실제로 사용할 때 주의해야 할 점, 그리고 기존 인증 방식과의 차이까지 정리해보았다. 2달정도 스프링부트-핵심가이드 도서를 통해 이론과 간단한 실습을 통해 백엔드를 학습했다. 앞으로 간단한 시스템을 구현해보고 프로젝트를 통해 스프링부트에 대해 한층 더 알아볼 예정이다.