사내에서 차세대 프로젝트에 참여하여 JWT 토큰 기반 인증 인가 개발을 할 기회가 있었다. 설계 단계에서 살펴 보니 필요한 정보를 JWT에 모두 담을 경우 토큰의 길이가 과도하게 길어질 수 있는 문제가 있었다. 사용자별로 다수의 데이터를 소유하고 있는 경우, 이러한 데이터를 토큰에 포함할 때 토큰 길이가 과도하게 길어져 토큰 크기가 일반적인 범위를 초과할 가능성이었다. 토큰의 장점인 무상태성을 유지하면서도 이 문제를 해결하기 위해 새로운 최적화 방안을 모색했다. 이 글은 당시 고민하며 정리했던 글이다. 주요 용어나 코드는 컨셉용으로 대체하였다.
사용자 인증 프로세스는 일반적인 토큰 기반 인증 시스템을 따릅니다. 즉, 사용자가 로그인을 요청하면, 사용자의 ID, 이름, 기타 정보 등을 포함하여 JWT 토큰을 생성하고, 이를 클라이언트에게 전달합니다.
클라이언트 측에서는 이 토큰을 이용하여 사용자 식별하고 권한에 따라 개인화된 사용자 화면을 구성합니다.
이러한 시나리오에서 JWT 토큰 생성 예시는 다음과 같습니다.
private String createToken(String userId, long tokenValidityMilliseconds, AdditionalUserInfo additionalUserInfo) {
Date now = new Date();
Date validity = new Date(now.getTime() + tokenValidityMilliseconds);
return Jwts.builder()
.subject(userId)
.claim("additionalUserInfo", additionalUserInfo)
.issuedAt(now)
.expiration(validity)
.signWith(secretKey(), SignatureAlgorithm.HS256)
.compact();
}
이러한 설계에서의 문제는 데이터의 과다함에 있습니다. 특히, 다수의 항목을 관리하는 경우, 토큰 길이가 과도하게 커질 수 있어 전송과 처리 과정에서 비효율을 초래합니다. 예를 들어, 7개 항목의 정보가 포함된 경우, SHA256과 base64 인코딩을 사용했을 때 토큰 길이는 1865자(1865 바이트)입니다.