Spring Security와 JWT를 이용한 무상태(Stateless) 인증 시스템 구축
1. 인증 방식의 진화: Session에서 JWT로
웹 서비스가 발전하면서 세션 기반의 인증 방식은 서버의 확장성 면에서 한계를 보이게 되었습니다. 서버에 상태를 저장하지 않는 무상태(Stateless) 인증 방식인 **JWT(JSON Web Token)**가 대중적으로 사용되고 있습니다.
2. JWT의 구조 이해
- Header: 토큰 타입(JWT)과 서명 알고리즘(HS256 등) 정보.
- Payload: 토큰에 담길 정보(Claims, 사용자 ID, 만료 시간 등).
- Signature: Header와 Payload를 조합하여 생성된 서명값. 위변조 방지.
3. Spring Security 필터 체인 설정
JWT는 요청마다 헤더의 Authorization: Bearer <token> 값을 검사해야 하므로 전용 필터를 추가해 줍니다.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
4. JWT 생성 로직 (Java)
public String generateToken(String username) {
long now = System.currentTimeMillis();
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date(now))
.setExpiration(new Date(now + 3600000)) // 1시간 만료
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
5. 보안 고려사항: Refresh Token의 도입
Access Token은 탈취 위험 때문에 만료 시간을 짧게(예: 30분) 설정합니다. 대신 유효 기간이 긴 Refresh Token을 별도의 안전한 저장소(Redis 등)에 보관하여 Access Token 재발급을 처리하는 것이 일반적입니다.
6. 결론
Spring Security와 JWT의 조합은 안전하고 확장성 있는 서비스를 구축하기 위한 필수적인 기술입니다. 프로젝트의 보안 요구사항에 맞춰 적절한 보안 전략을 수립해 보세요.