Skip to content

Commit defa072

Browse files
authored
release: 0.1.1 (#66)
2 parents 0050160 + 797342e commit defa072

5 files changed

Lines changed: 56 additions & 22 deletions

File tree

app-api/src/main/kotlin/site/techmoa/app/auth/v1/AuthController.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package site.techmoa.app.auth.v1
22

3+
import org.slf4j.LoggerFactory
34
import org.springframework.web.bind.annotation.GetMapping
45
import org.springframework.web.bind.annotation.RequestParam
56
import org.springframework.web.bind.annotation.RestController
@@ -12,11 +13,15 @@ class AuthController(
1213
private val oauthLoginUseCase: OauthLoginUseCase
1314
) {
1415

16+
private val log = LoggerFactory.getLogger(this.javaClass)
17+
1518
@GetMapping("/v1/oauth/kakao/callback")
1619
fun kakaoAuthorization(
1720
@RequestParam("code") code: String,
1821
): ApiResponse<LoginResponse> {
22+
log.info("[OAuth] Kakao authorization callback received, code length: ${code.length}")
1923
val token = oauthLoginUseCase.process(code)
24+
log.info("[OAuth] Login successful, access token issued for memberId: masked")
2025
return ApiResponse.success(LoginResponse(token.accessToken))
2126
}
2227
}

app-core/src/main/kotlin/site/techmoa/app/core/auth/OauthLoginUseCase.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package site.techmoa.app.core.auth
22

3+
import org.slf4j.LoggerFactory
34
import org.springframework.stereotype.Service
45
import site.techmoa.app.core.auth.dto.AuthToken
56
import site.techmoa.app.core.auth.port.ExternalAuthProvider
@@ -13,9 +14,16 @@ class OauthLoginUseCase(
1314
private val tokenProvider: TokenProvider
1415

1516
) {
17+
private val log = LoggerFactory.getLogger(this.javaClass)
18+
1619
fun process(code: String): AuthToken {
20+
log.info("[OAuth] Processing OAuth login with code length: ${code.length}")
1721
val memberResource = externalAuthProvider.getMemberResource(code)
22+
log.info("[OAuth] Member resource received - provider: ${memberResource.provider}, email: ${memberResource.email}, subject: ${memberResource.subject}")
1823
val member = memberUseCase.findOrCreate(memberResource)
19-
return tokenProvider.issue(member.id)
24+
log.info("[OAuth] Member found/created - memberId: ${member.id}")
25+
val authToken = tokenProvider.issue(member.id)
26+
log.info("[OAuth] Token issued successfully")
27+
return authToken
2028
}
2129
}

app-infra/app-infra-oauth/src/main/kotlin/site/techmoa/app/infra/oauth/JwtOIDCProvider.kt

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package site.techmoa.app.infra.oauth
22

3-
import io.jsonwebtoken.*
3+
import com.fasterxml.jackson.databind.ObjectMapper
4+
import io.jsonwebtoken.Claims
5+
import io.jsonwebtoken.ExpiredJwtException
6+
import io.jsonwebtoken.Jws
7+
import io.jsonwebtoken.Jwts
48
import org.slf4j.LoggerFactory
59
import org.springframework.stereotype.Component
610
import site.techmoa.app.infra.jwt.InvalidTokenException
@@ -21,34 +25,35 @@ class JwtOIDCProvider {
2125
}
2226

2327
private val log = LoggerFactory.getLogger(this.javaClass)
28+
private val objectMapper = ObjectMapper()
2429

2530
fun getKidFromUnsignedTokenHeader(token: String, iss: String, aud: String): String {
26-
return getUnsignedTokenClaims(token, iss, aud).header[KID] as String
27-
}
28-
29-
private fun getUnsignedTokenClaims(token: String, iss: String, aud: String): Jwt<Header, Claims> {
31+
log.info("[JWT] Extracting kid from unsigned token header - token length: ${token.length}, expected issuer: $iss, expected audience: $aud")
3032
try {
31-
return Jwts.parser()
32-
.requireIssuer(iss)
33-
.requireAudience(aud)
34-
.build()
35-
.parseUnsecuredClaims(getUnsignedToken(token))
36-
} catch (e: ExpiredJwtException) {
37-
throw RuntimeException("mma")
33+
val splitToken = token.split('.')
34+
log.info("[JWT] Splitting token - parts: ${splitToken.size}")
35+
if (splitToken.size != 3) {
36+
log.error("[JWT] Invalid token format - expected 3 parts, got ${splitToken.size}")
37+
throw InvalidTokenException("Invalid idToken format: expected 3 parts, got ${splitToken.size}")
38+
}
39+
val headerJson = String(Base64.getUrlDecoder().decode(splitToken[0]))
40+
val kid = objectMapper.readTree(headerJson).path(KID).asText()
41+
if (kid.isBlank()) {
42+
log.error("[JWT] Missing kid in token header")
43+
throw InvalidTokenException("Invalid idToken format: missing kid in token header")
44+
}
45+
log.info("[JWT] kid extracted from token header")
46+
return kid
3847
} catch (e: Exception) {
39-
log.error(e.toString());
40-
throw RuntimeException()
48+
log.error("[JWT] Failed to extract kid from token header", e)
49+
throw RuntimeException("Failed to extract kid: ${e.message}")
4150
}
4251
}
4352

44-
private fun getUnsignedToken(token: String): String {
45-
val splitToken = token.split("\\.")
46-
if (splitToken.size != 3) throw InvalidTokenException("Invalid idToken format: $token")
47-
return splitToken[0] + "." + splitToken[1] + "."
48-
}
49-
5053
fun getPayload(token: String, n: String, e: String): OIDCPayload {
54+
log.info("[JWT] Extracting payload from signed token - token length: ${token.length}")
5155
val payload = getTokenJws(token, n, e).payload
56+
log.info("[JWT] Payload extracted successfully - issuer: ${payload.issuer}, audience: ${payload.audience}, subject: ${payload.subject}, email: ${payload[EMAIL]}")
5257
return OIDCPayload(
5358
issuer = payload.issuer,
5459
audience = payload.audience.toString(),

app-infra/app-infra-oauth/src/main/kotlin/site/techmoa/app/infra/oauth/OIDCHelper.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package site.techmoa.app.infra.oauth
22

3+
import org.slf4j.LoggerFactory
34
import org.springframework.stereotype.Component
45
import site.techmoa.app.infra.oauth.dto.OIDCPayload
56
import site.techmoa.app.infra.oauth.dto.OIDCPubKeyDto
@@ -11,11 +12,17 @@ class OIDCHelper(
1112
properties: OauthProperties
1213
) {
1314

15+
private val log = LoggerFactory.getLogger(this.javaClass)
1416
private val property = properties.kakao
1517

1618
fun getPayload(idToken: String, pubKeys: OIDCPubKeys): OIDCPayload {
19+
log.info("[OIDC] Extracting kid from unsigned token - expected issuer: ${property.baseUrl}, expected audience: ${property.clientId}")
1720
val kid = getKidFromUnsignedToken(idToken, property.baseUrl, property.clientId)
21+
log.info("[OIDC] Kid extracted: $kid")
22+
log.info("[OIDC] Matching public key for kid: $kid")
1823
val pubKey = getPubKey(pubKeys, kid)
24+
log.info("[OIDC] Public key matched - alg: ${pubKey.alg}, use: ${pubKey.use}")
25+
log.info("[OIDC] Extracting payload with public key")
1926
return getPayload(idToken, pubKey)
2027
}
2128

@@ -28,7 +35,7 @@ class OIDCHelper(
2835
private fun getPubKey(
2936
pubKeys: OIDCPubKeys,
3037
kid: String
31-
): OIDCPubKeyDto = pubKeys.keys.firstOrNull { it.kid == kid } ?: throw RuntimeException("No matched keys")
38+
): OIDCPubKeyDto = pubKeys.keys.firstOrNull { it.kid == kid } ?: throw RuntimeException("No matched keys for kid: $kid")
3239

3340
private fun getPayload(
3441
idToken: String,

app-infra/app-infra-oauth/src/main/kotlin/site/techmoa/app/infra/oauth/kakao/KakaoAuthProvider.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package site.techmoa.app.infra.oauth.kakao
22

3+
import org.slf4j.LoggerFactory
34
import org.springframework.stereotype.Component
45
import site.techmoa.app.core.auth.OauthProvider
56
import site.techmoa.app.core.auth.dto.MemberResource
@@ -11,10 +12,18 @@ class KakaoAuthProvider(
1112
private val kakaoRestClient: KakaoRestClient,
1213
private val oidcHelper: OIDCHelper
1314
) : ExternalAuthProvider {
15+
private val log = LoggerFactory.getLogger(this.javaClass)
16+
1417
override fun getMemberResource(code: String): MemberResource {
18+
log.info("[Kakao OAuth] Fetching token from Kakao")
1519
val kakaoToken = kakaoRestClient.getToken(code)
20+
log.info("[Kakao OAuth] Token received - idToken length: ${kakaoToken.idToken.length}, scope: ${kakaoToken.scope}")
21+
log.info("[Kakao OAuth] Fetching public keys from Kakao")
1622
val keys = kakaoRestClient.getPubKeys()
23+
log.info("[Kakao OAuth] Public keys received - count: ${keys.keys.size}")
24+
log.info("[Kakao OAuth] Validating ID token")
1725
val payload = oidcHelper.getPayload(kakaoToken.idToken, keys)
26+
log.info("[Kakao OAuth] ID token validated - issuer: ${payload.issuer}, audience: ${payload.audience}, subject: ${payload.subject}, email: ${payload.email}")
1827
return MemberResource(
1928
email = payload.email,
2029
provider = OauthProvider.KAKAO,

0 commit comments

Comments
 (0)