refactor: auth 도메인에 새로 추가된 MemberFinder, MemberWriter 반영

This commit is contained in:
이상진 2025-08-04 17:26:41 +09:00
parent 76c5524c90
commit 35b7f06c2d
5 changed files with 48 additions and 53 deletions

View File

@ -3,64 +3,56 @@ package roomescape.auth.business
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import roomescape.auth.exception.AuthErrorCode
import roomescape.auth.exception.AuthException
import roomescape.auth.infrastructure.jwt.JwtHandler
import roomescape.auth.web.LoginCheckResponse
import roomescape.auth.web.LoginRequest
import roomescape.auth.web.LoginResponse
import roomescape.common.exception.RoomescapeException
import roomescape.member.business.MemberService
import roomescape.member.implement.MemberFinder
import roomescape.member.infrastructure.persistence.MemberEntity
private val log: KLogger = KotlinLogging.logger {}
@Service
class AuthService(
private val memberService: MemberService,
private val memberFinder: MemberFinder,
private val jwtHandler: JwtHandler,
) {
@Transactional(readOnly = true)
fun login(request: LoginRequest): LoginResponse {
val params = "email=${request.email}, password=${request.password}"
log.debug { "[AuthService.login] 로그인 시작: $params" }
log.info { "[AuthService.login] 시작: $params" }
val member: MemberEntity = fetchMemberOrThrow(AuthErrorCode.LOGIN_FAILED, params, "login") {
memberService.findByEmailAndPassword(request.email, request.password)
val member: MemberEntity = fetchOrThrow(AuthErrorCode.LOGIN_FAILED) {
memberFinder.findByEmailAndPassword(request.email, request.password)
}
val accessToken: String = jwtHandler.createToken(member.id!!)
return LoginResponse(accessToken)
.also { log.info { "[AuthService.login] 로그인 완료: memberId=${member.id}" } }
.also { log.info { "[AuthService.login] 완료: email=${request.email}, memberId=${member.id}" } }
}
@Transactional(readOnly = true)
fun checkLogin(memberId: Long): LoginCheckResponse {
log.debug { "[AuthService.checkLogin] 로그인 확인 시작: memberId=$memberId" }
val member: MemberEntity =
fetchMemberOrThrow(AuthErrorCode.MEMBER_NOT_FOUND, "memberId=$memberId", "checkLogin") {
memberService.findById(memberId)
}
log.info { "[AuthService.checkLogin] 시작: memberId=$memberId" }
val member: MemberEntity = fetchOrThrow(AuthErrorCode.MEMBER_NOT_FOUND) { memberFinder.findById(memberId) }
return LoginCheckResponse(member.name, member.role.name)
.also { log.info { "[AuthService.checkLogin] 로그인 확인 완료: memberId=$memberId" } }
.also { log.info { "[AuthService.checkLogin] 완료: memberId=$memberId, role=${it.role}" } }
}
private fun fetchOrThrow(errorCode: AuthErrorCode, block: () -> MemberEntity): MemberEntity {
try {
return block()
} catch (e: Exception) {
throw AuthException(errorCode, e.message ?: errorCode.message)
}
}
fun logout(memberId: Long) {
log.info { "[AuthService.logout] 로그아웃: memberId=$memberId" }
}
private fun fetchMemberOrThrow(
errorCode: AuthErrorCode,
params: String,
calledBy: String,
block: () -> MemberEntity,
): MemberEntity {
try {
return block()
} catch (e: Exception) {
if (e !is RoomescapeException) {
log.warn(e) { "[AuthService.$calledBy] 회원 조회 실패: $params" }
}
throw AuthException(errorCode)
}
}
}

View File

@ -7,8 +7,8 @@ import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RestController
import roomescape.auth.docs.AuthAPI
import roomescape.auth.business.AuthService
import roomescape.auth.docs.AuthAPI
import roomescape.auth.web.support.MemberId
import roomescape.common.dto.response.CommonApiResponse

View File

@ -11,14 +11,14 @@ import org.springframework.web.servlet.HandlerInterceptor
import roomescape.auth.exception.AuthErrorCode
import roomescape.auth.exception.AuthException
import roomescape.auth.infrastructure.jwt.JwtHandler
import roomescape.member.business.MemberService
import roomescape.member.implement.MemberFinder
import roomescape.member.infrastructure.persistence.MemberEntity
private val log: KLogger = KotlinLogging.logger {}
@Component
class AuthInterceptor(
private val memberService: MemberService,
private val memberFinder: MemberFinder,
private val jwtHandler: JwtHandler
) : HandlerInterceptor {
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
@ -50,10 +50,10 @@ class AuthInterceptor(
private fun findMember(accessToken: String?): MemberEntity {
try {
val memberId = jwtHandler.getMemberIdFromToken(accessToken)
return memberService.findById(memberId)
return memberFinder.findById(memberId)
.also { MDC.put("member_id", "$memberId") }
} catch (e: Exception) {
log.info { "[AuthInterceptor] 회원 조회 실패. accessToken = ${accessToken}" }
log.info { "[AuthInterceptor] 회원 조회 실패. accessToken = $accessToken" }
val errorCode = AuthErrorCode.MEMBER_NOT_FOUND
throw AuthException(errorCode, e.message ?: errorCode.message)
}

View File

@ -6,23 +6,21 @@ import io.kotest.core.spec.style.BehaviorSpec
import io.kotest.matchers.shouldBe
import io.mockk.every
import io.mockk.mockk
import org.springframework.data.repository.findByIdOrNull
import roomescape.auth.exception.AuthErrorCode
import roomescape.auth.exception.AuthException
import roomescape.auth.infrastructure.jwt.JwtHandler
import roomescape.member.business.MemberService
import roomescape.member.exception.MemberErrorCode
import roomescape.member.exception.MemberException
import roomescape.member.implement.MemberFinder
import roomescape.member.infrastructure.persistence.MemberEntity
import roomescape.member.infrastructure.persistence.MemberRepository
import roomescape.util.JwtFixture
import roomescape.util.MemberFixture
import roomescape.util.TsidFactory
class AuthServiceTest : BehaviorSpec({
val memberRepository: MemberRepository = mockk()
val memberService = MemberService(TsidFactory, memberRepository)
val memberFinder: MemberFinder = mockk()
val jwtHandler: JwtHandler = JwtFixture.create()
val authService = AuthService(memberService, jwtHandler)
val authService = AuthService(memberFinder, jwtHandler)
val user: MemberEntity = MemberFixture.user()
Given("로그인 요청을 받으면") {
@ -31,7 +29,7 @@ class AuthServiceTest : BehaviorSpec({
Then("회원이 있다면 JWT 토큰을 생성한 뒤 반환한다.") {
every {
memberRepository.findByEmailAndPassword(request.email, request.password)
memberFinder.findByEmailAndPassword(request.email, request.password)
} returns user
val accessToken: String = authService.login(request).accessToken
@ -42,8 +40,8 @@ class AuthServiceTest : BehaviorSpec({
Then("회원이 없다면 예외를 던진다.") {
every {
memberRepository.findByEmailAndPassword(request.email, request.password)
} returns null
memberFinder.findByEmailAndPassword(request.email, request.password)
} throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND)
val exception = shouldThrow<AuthException> {
authService.login(request)
@ -59,7 +57,7 @@ class AuthServiceTest : BehaviorSpec({
val userId: Long = user.id!!
Then("회원이 있다면 회원의 이름을 반환한다.") {
every { memberRepository.findByIdOrNull(userId) } returns user
every { memberFinder.findById(userId) } returns user
val response = authService.checkLogin(userId)
@ -69,7 +67,9 @@ class AuthServiceTest : BehaviorSpec({
}
Then("회원이 없다면 예외를 던진다.") {
every { memberRepository.findByIdOrNull(userId) } returns null
every {
memberFinder.findById(userId)
} throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND)
val exception = shouldThrow<AuthException> {
authService.checkLogin(userId)

View File

@ -4,12 +4,13 @@ import com.ninjasquad.springmockk.SpykBean
import io.mockk.every
import org.hamcrest.Matchers.equalTo
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.data.repository.findByIdOrNull
import org.springframework.test.web.servlet.MockMvc
import roomescape.auth.business.AuthService
import roomescape.auth.exception.AuthErrorCode
import roomescape.common.exception.CommonErrorCode
import roomescape.common.exception.ErrorCode
import roomescape.member.exception.MemberErrorCode
import roomescape.member.exception.MemberException
import roomescape.util.MemberFixture
import roomescape.util.RoomescapeApiTest
@ -31,7 +32,7 @@ class AuthControllerTest(
val expectedToken = "expectedToken"
every {
memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password)
memberFinder.findByEmailAndPassword(userRequest.email, userRequest.password)
} returns user
every {
@ -52,8 +53,8 @@ class AuthControllerTest(
When("회원을 찾지 못하면") {
every {
memberRepository.findByEmailAndPassword(userRequest.email, userRequest.password)
} returns null
memberFinder.findByEmailAndPassword(userRequest.email, userRequest.password)
} throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND)
Then("에러 응답을 받는다.") {
val expectedError = AuthErrorCode.LOGIN_FAILED
@ -111,7 +112,9 @@ class AuthControllerTest(
val invalidMemberId: Long = -1L
every { jwtHandler.getMemberIdFromToken(any()) } returns invalidMemberId
every { memberRepository.findByIdOrNull(invalidMemberId) } returns null
every {
memberFinder.findById(invalidMemberId)
} throws MemberException(MemberErrorCode.MEMBER_NOT_FOUND)
Then("에러 응답을 받는다.") {
val expectedError = AuthErrorCode.MEMBER_NOT_FOUND
@ -134,7 +137,7 @@ class AuthControllerTest(
} returns 1L
every {
memberRepository.findByIdOrNull(1L)
memberFinder.findById(1L)
} returns MemberFixture.create(id = 1L)
Then("정상 응답한다.") {