소개
현대 웹 애플리케이션에서 보안은 매우 중요한 요소입니다. 이 포스트에서는 Spring Boot 애플리케이션에서 JWT(JSON Web Token)와 Redis를 사용하여 안전하고 효율적인 인증 시스템을 구현하는 방법을 알아보겠습니다.
프로젝트는 다음과 같은 환경에서 구축되었습니다:
- Spring Boot
- Java
- Gradle
- Docker
- Redis
- GitHub Actions (CI/CD)
인증 프로세스 개요
구현할 인증 프로세스는 다음과 같습니다:
- 클라이언트의 로그인 요청
- 아이디/비밀번호 검증 후 Access Token과 Refresh Token 발급
- Refresh Token은 Redis에 저장하고, 클라이언트에 두 토큰 모두 응답
- 클라이언트의 API 호출 시, Access Token이 만료되었다면 Refresh Token을 검증하여 새로운 Access Token 재발급
의존성 추가
build.gradle 파일에 다음 의존성을 추가합니다:
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
// JWT 관련 추가 의존성
implementation 'com.sun.xml.bind:jaxb-impl:4.0.1'
implementation 'com.sun.xml.bind:jaxb-core:4.0.1'
implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'
Redis 설정
Docker Compose를 사용하여 Redis 환경을 구축합니다. docker-compose.yml 파일의 예시:
version: '3'
services:
redis:
image: redis:latest
ports:
- "6379:6379"
Spring Boot 애플리케이션에서 Redis 설정:
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisHost, redisPort);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
return template;
}
}
JWT 구현
JWT 생성 및 검증을 위한 유틸리티 클래스를 만듭니다:
@Component
public class JwtTokenProvider {
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.accessTokenValidityInMilliseconds}")
private long accessTokenValidityInMilliseconds;
@Value("${jwt.refreshTokenValidityInMilliseconds}")
private long refreshTokenValidityInMilliseconds;
public String createAccessToken(Authentication authentication) {
// Access Token 생성 로직
}
public String createRefreshToken() {
// Refresh Token 생성 로직
}
public boolean validateToken(String token) {
// 토큰 검증 로직
}
// 기타 필요한 메소드들...
}
사용자 인증 서비스
사용자 인증을 처리할 서비스를 구현합니다:
@Service
public class AuthService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final JwtTokenProvider jwtTokenProvider;
private final RedisTemplate<String, Object> redisTemplate;
// 생성자 주입
public TokenDto login(LoginDto loginDto) {
// 로그인 로직 구현
}
public TokenDto reissue(TokenRequestDto tokenRequestDto) {
// 토큰 재발급 로직 구현
}
// 기타 필요한 메소드들...
}
Redis를 이용한 Refresh Token 관리
Redis에 Refresh Token을 저장하고 관리하는 로직을 구현합니다:
@Service
public class RefreshTokenService {
private final RedisTemplate<String, Object> redisTemplate;
private final JwtTokenProvider jwtTokenProvider;
// 생성자 주입
public void saveRefreshToken(String username, String refreshToken) {
// Refresh Token을 Redis에 저장
}
public String getRefreshToken(String username) {
// Redis에서 Refresh Token 조회
}
public void deleteRefreshToken(String username) {
// Redis에서 Refresh Token 삭제
}
}
인증 컨트롤러 구현
인증 관련 엔드포인트를 처리할 컨트롤러를 구현합니다:
@RestController
@RequestMapping("/api/auth")
public class AuthController {
private final AuthService authService;
// 생성자 주입
@PostMapping("/login")
public ResponseEntity<TokenDto> login(@RequestBody LoginDto loginDto) {
// 로그인 처리
}
@PostMapping("/reissue")
public ResponseEntity<TokenDto> reissue(@RequestBody TokenRequestDto tokenRequestDto) {
// 토큰 재발급 처리
}
// 기타 필요한 엔드포인트들...
}
보안 설정
Spring Security 설정을 통해 인증 및 인가를 구현합니다:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtTokenProvider jwtTokenProvider;
// 생성자 주입
@Override
protected void configure(HttpSecurity http) throws Exception {
// 보안 설정 구현
}
// 기타 필요한 설정들...
}
결론
이 글에서는 Spring Boot 애플리케이션에서 JWT와 Redis를 사용하여 안전하고 효율적인 인증 시스템을 구현하는 방법을 살펴보았습니다. 이 방식은 서버의 상태를 최소화하면서도 보안성을 높일 수 있는 장점이 있습니다.
향후 개선 사항으로는 토큰 암호화, 멀티 디바이스 지원, 그리고 보안 감사 로깅 등을 고려해볼 수 있습니다.
'심층 기술 분석 (Deep Tech Dive) > Spring Boot 심층 분석' 카테고리의 다른 글
Spring Boot와 JPA를 활용한 효율적인 데이터베이스 스키마 관리 (6) | 2024.10.15 |
---|---|
Spring Boot와 JPA를 활용한 MySQL 데이터베이스 구축: 심층 분석 및 문제 해결 과정 (1) | 2024.10.14 |
Spring Boot 프로젝트의 데이터베이스 선택과 AWS 호스팅 설정: MySQL (2) | 2024.10.13 |
Spring Boot에서 WebSocket 구현 심층 분석: 실시간 비디오 전송 시스템 (2) | 2024.10.13 |