Skip to content

Commit

Permalink
refactor: 로그인 토큰과 회원가입 토큰을 AuthToken 으로 추상화
Browse files Browse the repository at this point in the history
  • Loading branch information
Combi153 committed Apr 7, 2024
1 parent 18daef0 commit 6ebdfef
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ class AuthTokenService(
}

override fun createAuthToken(memberId: Long, authority: Authority): AuthTokenInfo {
val authToken = authTokenProvider.createAuthToken(memberId, authority, Date())
val authToken = authTokenProvider.createLoginAuthToken(memberId, authority, Date())
refreshTokenRepository.deleteByMemberId(memberId)
refreshTokenRepository.save(
RefreshToken(
memberId = memberId,
token = authToken.refreshToken
token = authToken.getRefreshToken()
)
)
return AuthTokenInfo.from(authToken)
return AuthTokenInfo(authToken)
}

private fun createSignUpToken(authCredentialsId: Long): AuthTokenInfo {
val authToken = authTokenProvider.createSignUpAuthToken(authCredentialsId, Date())
return AuthTokenInfo.signUpTokenOf(authToken)
return AuthTokenInfo(authToken)
}
}
32 changes: 9 additions & 23 deletions src/main/kotlin/com/petqua/application/token/TokenDtos.kt
Original file line number Diff line number Diff line change
@@ -1,34 +1,20 @@
package com.petqua.application.token

import com.petqua.domain.auth.token.AuthToken
import com.petqua.presentation.auth.SignUpTokenResponse

data class AuthTokenInfo(
val accessToken: String,
val refreshToken: String,
val authToken: AuthToken,
) {
val accessToken: String
get() = authToken.getAccessToken()

fun isSignUpNeeded(): Boolean {
return AuthToken.isSignUpNeeded(refreshToken)
}
val refreshToken: String
get() = authToken.getRefreshToken()

fun toSignUpTokenResponse(): SignUpTokenResponse {
return SignUpTokenResponse(accessToken)
}
val signUpToken: String
get() = authToken.getSignUpToken()

companion object {
fun from(authToken: AuthToken): AuthTokenInfo {
return AuthTokenInfo(
accessToken = authToken.accessToken,
refreshToken = authToken.refreshToken,
)
}

fun signUpTokenOf(signUpToken: AuthToken): AuthTokenInfo {
return AuthTokenInfo(
accessToken = signUpToken.accessToken,
refreshToken = signUpToken.refreshToken
)
}
fun isSignUpNeeded(): Boolean {
return authToken.isSignUpNeeded()
}
}
30 changes: 16 additions & 14 deletions src/main/kotlin/com/petqua/domain/auth/token/AuthToken.kt
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
package com.petqua.domain.auth.token

private const val EMPTY_TOKEN = ""
abstract class AuthToken {

class AuthToken private constructor(
val accessToken: String,
val refreshToken: String,
) {
protected abstract fun isSignUpToken(): Boolean

abstract fun getAccessToken(): String

abstract fun getRefreshToken(): String

abstract fun getSignUpToken(): String

fun isSignUpNeeded(): Boolean {
return isSignUpToken()
}

companion object {
fun of(accessToken: String, refreshToken: String): AuthToken {
return AuthToken(
fun loginTokenOf(accessToken: String, refreshToken: String): AuthToken {
return LoginToken(
accessToken = accessToken,
refreshToken = refreshToken,
)
}

fun signUpTokenOf(signUpToken: String): AuthToken {
return AuthToken(
accessToken = signUpToken,
refreshToken = EMPTY_TOKEN
return SignUpToken(
signUpToken = signUpToken,
)
}

fun isSignUpNeeded(token: String): Boolean {
return token == EMPTY_TOKEN
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class AuthTokenProvider(
private val properties: AuthTokenProperties,
) {

fun createAuthToken(memberId: Long, authority: Authority, issuedDate: Date): AuthToken {
fun createLoginAuthToken(memberId: Long, authority: Authority, issuedDate: Date): AuthToken {
val accessToken = AccessTokenClaims(memberId, authority)
return AuthToken.of(
return AuthToken.loginTokenOf(
accessToken = jwtProvider.createToken(accessToken.getClaims(), properties.accessTokenLiveTime, issuedDate),
refreshToken = jwtProvider.createToken(EMPTY_SUBJECT, properties.refreshTokenLiveTime, issuedDate)
)
Expand Down
27 changes: 27 additions & 0 deletions src/main/kotlin/com/petqua/domain/auth/token/LoginToken.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.petqua.domain.auth.token


import com.petqua.exception.auth.AuthException
import com.petqua.exception.auth.AuthExceptionType.UNSUPPORTED_OPERATION

class LoginToken(
private val accessToken: String,
private val refreshToken: String,
) : AuthToken() {

override fun isSignUpToken(): Boolean {
return false
}

override fun getAccessToken(): String {
return accessToken
}

override fun getRefreshToken(): String {
return refreshToken
}

override fun getSignUpToken(): String {
throw AuthException(UNSUPPORTED_OPERATION)
}
}
25 changes: 25 additions & 0 deletions src/main/kotlin/com/petqua/domain/auth/token/SignUpToken.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.petqua.domain.auth.token

import com.petqua.exception.auth.AuthException
import com.petqua.exception.auth.AuthExceptionType

class SignUpToken(
private val signUpToken: String,
) : AuthToken() {

override fun isSignUpToken(): Boolean {
return true
}

override fun getAccessToken(): String {
throw AuthException(AuthExceptionType.UNSUPPORTED_OPERATION)
}

override fun getRefreshToken(): String {
throw AuthException(AuthExceptionType.UNSUPPORTED_OPERATION)
}

override fun getSignUpToken(): String {
return signUpToken
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ enum class AuthExceptionType(
UNSUPPORTED_AUTHORITY(BAD_REQUEST, "A20", "해당하는 권한이 존재하지 않습니다."),

NOT_RENEWABLE_ACCESS_TOKEN(BAD_REQUEST, "A30", "유효한 AccessToken은 갱신할 수 없습니다."),

UNSUPPORTED_OPERATION(HttpStatus.INTERNAL_SERVER_ERROR, "A40", "지원하지 않는 메서드를 호출했습니다."),
;

override fun httpStatus(): HttpStatus {
Expand Down
11 changes: 5 additions & 6 deletions src/main/kotlin/com/petqua/presentation/auth/AuthController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.petqua.common.config.ACCESS_TOKEN_SECURITY_SCHEME_KEY
import com.petqua.domain.auth.Auth
import com.petqua.domain.auth.LoginMember
import com.petqua.domain.auth.oauth.OauthServerType
import com.petqua.domain.auth.token.AuthToken
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.enums.ParameterIn
Expand Down Expand Up @@ -72,7 +71,7 @@ class AuthController(
val authTokenInfo = authFacadeService.login(oauthServerType, code)

if (authTokenInfo.isSignUpNeeded()) {
return ResponseEntity.status(CREATED).body(authTokenInfo.toSignUpTokenResponse())
return ResponseEntity.status(CREATED).body(SignUpTokenResponse(authTokenInfo.signUpToken))
}

val refreshTokenCookie = createRefreshTokenCookie(authTokenInfo.refreshToken)
Expand Down Expand Up @@ -106,9 +105,9 @@ class AuthController(
@ApiResponse(responseCode = "200", description = "재발급 성공")
@GetMapping("/token")
fun extendLogin(
@Parameter(hidden = true) @Auth authToken: AuthToken,
@Parameter(hidden = true) @Auth loginToken: LoginTokenRequest,
): ResponseEntity<Unit> {
val authTokenInfo = authFacadeService.extendLogin(authToken.accessToken, authToken.refreshToken)
val authTokenInfo = authFacadeService.extendLogin(loginToken.accessToken, loginToken.refreshToken)
val refreshTokenCookie = createRefreshTokenCookie(authTokenInfo.refreshToken)
val headers = HttpHeaders().apply {
set(AUTHORIZATION, authTokenInfo.accessToken)
Expand Down Expand Up @@ -144,9 +143,9 @@ class AuthController(
@SecurityRequirement(name = ACCESS_TOKEN_SECURITY_SCHEME_KEY)
@PatchMapping("/members/sign-out")
fun logOut(
@Parameter(hidden = true) @Auth authToken: AuthToken,
@Parameter(hidden = true) @Auth loginToken: LoginTokenRequest,
): ResponseEntity<Unit> {
authFacadeService.logOut(authToken.accessToken, authToken.refreshToken)
authFacadeService.logOut(loginToken.accessToken, loginToken.refreshToken)
return ResponseEntity.noContent().build()
}
}
5 changes: 5 additions & 0 deletions src/main/kotlin/com/petqua/presentation/auth/AuthDtos.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ data class SignUpTokenResponse(
)
val signUpToken: String,
)

data class LoginTokenRequest(
val accessToken: String,
val refreshToken: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.petqua.presentation.auth

import com.petqua.common.util.getHttpServletRequestOrThrow
import com.petqua.domain.auth.Auth
import com.petqua.domain.auth.token.AuthToken
import org.springframework.core.MethodParameter
import org.springframework.stereotype.Component
import org.springframework.web.bind.support.WebDataBinderFactory
Expand All @@ -17,19 +16,19 @@ class TokenArgumentResolver(

override fun supportsParameter(parameter: MethodParameter): Boolean {
return parameter.hasParameterAnnotation(Auth::class.java)
&& parameter.parameterType == AuthToken::class.java
&& parameter.parameterType == LoginTokenRequest::class.java
}

override fun resolveArgument(
parameter: MethodParameter,
mavContainer: ModelAndViewContainer?,
webRequest: NativeWebRequest,
binderFactory: WebDataBinderFactory?,
): AuthToken {
): LoginTokenRequest {
val request = webRequest.getHttpServletRequestOrThrow()
val accessToken = authExtractor.extractAccessToken(request)
authExtractor.validateBlacklistTokenRegardlessExpiration(accessToken)
val refreshToken = authExtractor.extractRefreshToken(request)
return AuthToken.of(accessToken, refreshToken)
return LoginTokenRequest(accessToken, refreshToken)
}
}
Loading

0 comments on commit 6ebdfef

Please sign in to comment.