JWT(JSON Web Token)는 RFC 7519에 정의된 토큰 기반 인증 방식으로, JSON 포맷을 사용해 정보를 안전하게 전송하기 위해 사용된다. 서버 측에서 세션 상태를 유지하지 않아도 되는 장점이 있어 인증(Authentication)과 권한(Authorization) 처리에 적합하다.
일반적으로 다음과 같은 구조로 구성된다:
Header.Payload.Signature
각 부분은 Base64 URL-safe 방식으로 인코딩되며, "."으로 연결된다.
JWT는 다음 3가지 파트로 구성된다.
{
"typ": "JWT",
"alg": "HS512"
}
토큰의 메타데이터로, 타입(typ)과 서명 알고리즘(alg)을 명시한다.
사용자 정보와 클레임(Claims)이 포함된다.
유형 | 설명 |
---|---|
Registered Claims | 표준 클레임 (iss, sub, aud, exp 등) |
Public Claims | 공개 클레임 (URI 네임스페이스 사용) |
Private Claims | 사용자 정의 클레임 |
{
"iss": "rest-api",
"aud": "rest-app",
"sub": "serveside",
"exp": 1561795832,
"rol": ["ROLE_MEMBER"]
}
Header와 Payload를 결합하고, 비밀 키와 알고리즘을 통해 서명해 위변조를 방지한다.
String token = username + "_" + roles;
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
String token = Jwts.builder()
.signWith(Keys.hmacShaKeyFor(signingKey), SignatureAlgorithm.HS512)
.setHeaderParam("typ", "JWT")
.setIssuer("issuer")
.setAudience("audience")
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + 864000000))
.claim("rol", roles)
.compact();
.claim("uid", username)
.claim("rol", roles)
민감 정보는 포함하지 않아야 하며, 정보는 Base64로 인코딩만 되므로 보호되지 않음에 주의해야 한다.
com.example.serveside.secret-key=your-secret-key-here
@ConfigurationProperties("com.example.serveside")
public class ShopProperties {
private String secretKey;
}
클라이언트가 HTTP 헤더에 포함해 요청:
Authorization: Bearer <JWT>
서버에서 파싱:
Jws<Claims> parsedToken = Jwts.parser()
.setSigningKey(signingKey)
.parseClaimsJws(token);
String username = parsedToken.getBody().getSubject();
Object roles = parsedToken.getBody().get("rol");
JWT는 무상태(stateless)이므로 다음과 같은 설정 필요:
SecurityFilterChain 또는 WebSecurityConfigurerAdapter 사용.
필터 클래스 | 설명 |
---|---|
SecurityContextPersistenceFilter | SecurityContext 유지 |
UsernamePasswordAuthenticationFilter | 로그인 요청 처리 |
LogoutFilter | 로그아웃 처리 |
FilterSecurityInterceptor | 접근 권한 확인 |
ExceptionTranslationFilter | 인증/인가 실패 처리 |
JWT는 RESTful API 시스템에서 널리 사용되는 인증 방식이다. 무상태 서버 구조에 적합하며, 클라이언트와 서버 간 인증 정보를 안전하게 주고받을 수 있다.
이번 정리를 통해 Header, Payload, Signature 각각의 역할과 생성 및 검증 방식, Spring Security 연동 등을 단계별로 살펴봤다. 실무에서는 클레임 설정, 만료 시간, 저장 방식 등 세부 전략도 함께 고민해야 한다.
민감 정보는 절대 포함하지 않으며, 비밀 키 보안 유지와 함께 Refresh Token, 블랙리스트 전략도 병행해 보안성을 높여야 한다.
JWT는 단순한 토큰이 아닌, 서비스 보안 정책을 설계하는 핵심 도구다.