From 7f1ab906b7b27383e48deaf3ca5ccfb6dbbd3280 Mon Sep 17 00:00:00 2001 From: pricelees Date: Thu, 11 Sep 2025 17:01:04 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20/=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=20=EA=B5=AC=EB=B6=84=EC=97=86=EB=8A=94=20'?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=83=81=ED=83=9C'=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20API=EC=99=80=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=EC=99=80=20=EC=83=81=EA=B4=80=EC=97=86?= =?UTF-8?q?=EC=9D=B4=20=EC=82=AC=EC=9A=A9=20=EA=B0=80=EB=8A=A5=ED=95=9C=20?= =?UTF-8?q?API=EC=97=90=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=83=88=EB=A1=9C?= =?UTF-8?q?=EC=9A=B4=20Interceptor=20=EB=B0=8F=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/web/support/AuthAnnotations.kt | 8 +++ .../interceptors/AuthenticatedInterceptor.kt | 50 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt diff --git a/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt b/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt index 55490e4b..f06e0bc2 100644 --- a/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt +++ b/src/main/kotlin/roomescape/auth/web/support/AuthAnnotations.kt @@ -23,3 +23,11 @@ annotation class AdminOnly( @Target(AnnotationTarget.FUNCTION) @Retention(AnnotationRetention.RUNTIME) annotation class UserOnly + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class Authenticated + +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +annotation class Public diff --git a/src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt b/src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt new file mode 100644 index 00000000..ff248ff1 --- /dev/null +++ b/src/main/kotlin/roomescape/auth/web/support/interceptors/AuthenticatedInterceptor.kt @@ -0,0 +1,50 @@ +package roomescape.auth.web.support.interceptors + +import io.github.oshai.kotlinlogging.KLogger +import io.github.oshai.kotlinlogging.KotlinLogging +import jakarta.servlet.http.HttpServletRequest +import jakarta.servlet.http.HttpServletResponse +import org.slf4j.MDC +import org.springframework.stereotype.Component +import org.springframework.web.method.HandlerMethod +import org.springframework.web.servlet.HandlerInterceptor +import roomescape.auth.business.AuthServiceV2 +import roomescape.auth.business.CLAIM_TYPE_KEY +import roomescape.auth.infrastructure.jwt.JwtUtils +import roomescape.auth.web.support.Authenticated +import roomescape.auth.web.support.MDC_MEMBER_ID_KEY +import roomescape.auth.web.support.accessToken +import roomescape.common.dto.PrincipalType + +private val log: KLogger = KotlinLogging.logger {} + +@Component +class AuthenticatedInterceptor( + private val jwtUtils: JwtUtils, + private val authService: AuthServiceV2 +) : HandlerInterceptor { + + override fun preHandle( + request: HttpServletRequest, + response: HttpServletResponse, + handler: Any + ): Boolean { + if ((handler !is HandlerMethod) || (handler.getMethodAnnotation(Authenticated::class.java) == null)) { + return true + } + + val token: String? = request.accessToken() + + val id = jwtUtils.extractSubject(token).also { MDC.put(MDC_MEMBER_ID_KEY, it) } + val type = jwtUtils.extractClaim(token, CLAIM_TYPE_KEY) + + try { + authService.findContextById(id.toLong(), PrincipalType.valueOf(type)) + log.info { "[AuthenticatedInterceptor] 인증 완료. id=$id, type=${type}" } + + return true + } catch (e: Exception) { + throw e + } + } +}