Spring Session에서 특정 API에 대해 세션 생성 방지하기
Spring 애플리케이션에서 /health
같은 특정 API 호출 시 불필요한 세션이 생성되지 않도록 하기 위한 방법을 정리합니다. 주로 SessionRepositoryFilter
커스터마이징과 필터 추가를 통해 이를 해결할 수 있습니다.
1. 문제 상황
기본적으로 Spring은 요청이 들어올 때 세션을 자동으로 생성합니다. 그러나 /health
와 같은 단순 API에 대해 세션 생성이 불필요할 수 있습니다. 특정 URL에 대해 세션 생성을 방지하고 싶다면, 이를 명시적으로 처리해야 합니다.
2. 커스텀 SessionRepositoryFilter
생성
SessionRepositoryFilter
를 확장하여, 특정 URL에 대해 세션이 생성되지 않도록 하는 필터를 작성할 수 있습니다.
import org.springframework.session.Session
import org.springframework.session.SessionRepository
import org.springframework.session.web.http.SessionRepositoryFilter
import javax.servlet.FilterChain
import javax.servlet.ServletException
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import javax.servlet.http.HttpServletRequest
class CustomSessionRepositoryFilter<S : Session>(
sessionRepository: SessionRepository<S>,
private val excludedUrls: List<String> = listOf("/health", "/actuator")
) : SessionRepositoryFilter<S>(sessionRepository) {
@Throws(ServletException::class)
override fun doFilterInternal(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
val httpRequest = request as HttpServletRequest
val path = httpRequest.requestURI
// 제외할 URL에 대해 세션 생성하지 않음
if (excludedUrls.any { path.startsWith(it) }) {
chain.doFilter(request, response)
} else {
super.doFilterInternal(request, response, chain)
}
}
}
위의 코드는 /health
나 /actuator
경로로 들어오는 요청에 대해 세션을 생성하지 않도록 설정합니다.
3. 필터를 Spring Bean으로 등록
필터를 빈으로 등록하여 특정 URL에 대한 요청에만 적용되도록 합니다.
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.Ordered
import org.springframework.session.Session
import org.springframework.session.SessionRepository
import org.springframework.session.web.http.SessionRepositoryFilter
@Configuration
class SessionFilterConfig {
@Bean
fun sessionFilter(sessionRepository: SessionRepository<*>): FilterRegistrationBean<SessionRepositoryFilter<*>> {
val filter = CustomSessionRepositoryFilter(sessionRepository)
val registration = FilterRegistrationBean<SessionRepositoryFilter<*>>()
registration.filter = filter
registration.order = Ordered.HIGHEST_PRECEDENCE
registration.addUrlPatterns("/*")
return registration
}
}
4. 세션 생성 여부 확인
일반적으로 사용하는 request.session 을 사용할 경우 getSession()이 호출되어 세션이 없을 경우 새로 생성하게 됩니다.
세션이 실제로 생성되었는지 여부를 확인하려면, HttpServletRequest.getSession(false)
를 사용하여 세션이 존재하는지 확인할 수 있습니다.
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.servlet.http.HttpServletRequest
@RestController
@RequestMapping("/session-test")
class SessionController {
@GetMapping("/check")
fun checkSession(request: HttpServletRequest): String {
val session = request.getSession(false) // 세션이 없으면 새로 생성하지 않음
return if (session == null) {
"Session not created"
} else {
"Session exists: ${session.id}"
}
}
}
이 코드는 /session-test/check
로 요청 시, 세션이 이미 존재하는지 여부를 확인해줍니다.
5. 결론
Spring 애플리케이션에서 /health
와 같은 경로에 대한 세션 생성을 방지하기 위해서는 필터를 적절히 구성하고, 필요에 따라 Spring Security 설정을 통해 세션 생성을 제어할 수 있습니다. 이 방법을 통해 불필요한 세션 생성을 막아 애플리케이션의 성능을 향상시킬 수 있습니다.