-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ISSUE-10 JWT Util 클래스 구현 #11
Changes from all commits
93c2c0c
574abb5
21c8ea8
e6a4bd2
5200430
ed7a37a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,19 @@ | ||
package org.doorip.core.auth | ||
|
||
import org.doorip.domain.UserId | ||
import org.springframework.stereotype.Component | ||
import org.doorip.support.jwt.JwtProvider | ||
import org.doorip.support.jwt.JwtSecretKey | ||
import org.springframework.stereotype.Service | ||
|
||
@Component | ||
internal class JwtService : AccessTokenUseCase { | ||
@Service | ||
internal class JwtService( | ||
private val jwtProvider: JwtProvider, | ||
private val jwtSecretKey: JwtSecretKey, | ||
) : AccessTokenUseCase { | ||
|
||
override fun getUserId(token: String): UserId? { | ||
// TODO | ||
return null | ||
val subject = jwtProvider.validateAndGetSubject(token, jwtSecretKey) ?: return null | ||
|
||
return UserId(subject.toLong()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.doorip.core.config | ||
|
||
import org.doorip.support.jwt.JwtProvider | ||
import org.doorip.support.jwt.JwtSecretKey | ||
import org.springframework.boot.context.properties.EnableConfigurationProperties | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
|
||
@EnableConfigurationProperties(JwtProperties::class) | ||
@Configuration | ||
internal class JwtConfig { | ||
|
||
@Bean | ||
fun jwtProvider(): JwtProvider = JwtProvider() | ||
|
||
@Bean | ||
fun jwtSecretKey(jwtProperties: JwtProperties): JwtSecretKey = JwtSecretKey(jwtProperties.secret) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.doorip.core.config | ||
|
||
import org.springframework.boot.context.properties.ConfigurationProperties | ||
|
||
@ConfigurationProperties(prefix = "jwt") | ||
data class JwtProperties( | ||
val secret: String, | ||
) | ||
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
jwt: | ||
secret: ${JWT_SECRET_KEY} |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -12,15 +12,8 @@ sealed class ClientException( | |||||||||
message: String, | ||||||||||
) : DooripException(code, message) | ||||||||||
|
||||||||||
class UnauthorizedException( | ||||||||||
code: String, | ||||||||||
message: String, | ||||||||||
) : ClientException(code, message) | ||||||||||
|
||||||||||
class UnauthenticatedException( | ||||||||||
code: String, | ||||||||||
message: String, | ||||||||||
) : ClientException(code, message) | ||||||||||
data object UnauthorizedException : ClientException("e4030", "인가 과정에서 예외가 발생했습니다.") { private fun readResolve(): Any = UnauthorizedException } | ||||||||||
data object UnauthenticatedException : ClientException("e4010", "인증 과정에서 예외가 발생했습니다. (ex. AT 만료 or RT 만료)") { private fun readResolve(): Any = UnauthenticatedException } | ||||||||||
Comment on lines
+15
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 예외 처리 구조에 대한 제안이 있습니다! 🏗️ JWT 관련 예외들을 위한 별도의 sealed 클래스를 만드는 것을 고려해보세요. 이렇게 하면 JWT 관련 예외들을 더 체계적으로 관리할 수 있습니다. 예시 구조: sealed class JwtException(
code: String,
message: String
) : ClientException(code, message)
data object TokenExpiredException : JwtException("e4011", "인증 토큰이 만료되었습니다.")
data object InvalidTokenException : JwtException("e4012", "유효하지 않은 토큰입니다.") 🧹 Nitpick (assertive) 예외 메시지를 더 명확하게 개선하면 좋을 것 같아요! 📝 현재 예외 메시지가 다소 모호할 수 있습니다. JWT 컨텍스트에서 더 구체적인 정보를 제공하면 좋을 것 같아요. 다음과 같이 메시지를 개선하는 것을 제안드립니다: -data object UnauthorizedException : ClientException("e4030", "인가 과정에서 예외가 발생했습니다.") { private fun readResolve(): Any = UnauthorizedException }
+data object UnauthorizedException : ClientException("e4030", "해당 리소스에 대한 접근 권한이 없습니다.") { private fun readResolve(): Any = UnauthorizedException }
-data object UnauthenticatedException : ClientException("e4010", "인증 과정에서 예외가 발생했습니다. (ex. AT 만료 or RT 만료)") { private fun readResolve(): Any = UnauthenticatedException }
+data object UnauthenticatedException : ClientException("e4010", "인증이 필요하거나 제공된 인증 토큰이 만료되었습니다.") { private fun readResolve(): Any = UnauthenticatedException } 📝 Committable suggestion
Suggested change
|
||||||||||
|
||||||||||
data object InvalidRequestValueException : ClientException("e4000", "잘못된 요청입니다.") { private fun readResolve(): Any = InvalidRequestValueException } | ||||||||||
data object MethodNotAllowedException : ClientException("e4050", "잘못된 HTTP method 요청입니다.") { private fun readResolve(): Any = MethodNotAllowedException } | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,5 @@ include( | |
"domain", | ||
"gateway:rdb", | ||
"support:yaml", | ||
"support:jwt", | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import org.springframework.boot.gradle.tasks.bundling.BootJar | ||
|
||
dependencies { | ||
implementation("io.jsonwebtoken:jjwt-api:${Versions.JJWT}") | ||
runtimeOnly("io.jsonwebtoken:jjwt-impl:${Versions.JJWT}") | ||
runtimeOnly("io.jsonwebtoken:jjwt-jackson:${Versions.JJWT}") | ||
Comment on lines
+4
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) 💡 Codebase verification JJWT 라이브러리 버전 업데이트가 필요해요! 🔄 현재 프로젝트에서 사용 중인 JJWT 버전(0.12.5)이 최신 버전(0.12.6)보다 낮네요. 보안과 안정성을 위해 업데이트를 추천드립니다! • 추가로 제안드린 BOM 방식의 의존성 관리도 고려해보시면 좋을 것 같아요. 버전 관리가 더욱 편리해질 거예요! 😊 🔗 Analysis chain의존성 버전 관리에 대한 제안 안녕하세요! JJWT 라이브러리 의존성 설정에 대해 몇 가지 조언을 드리고 싶어요. 📚 JJWT 버전의 호환성과 보안 업데이트를 확인해볼까요? 의존성 선언을 조금 더 명확하게 정리하면 어떨까요? val jjwtVersion = Versions.JJWT
dependencies {
implementation(platform("io.jsonwebtoken:jjwt-bom:$jjwtVersion"))
implementation("io.jsonwebtoken:jjwt-api")
runtimeOnly("io.jsonwebtoken:jjwt-impl")
runtimeOnly("io.jsonwebtoken:jjwt-jackson")
} 이렇게 하면 BOM(Bill of Materials)을 통해 버전을 일관성 있게 관리할 수 있어요! 😊 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# JJWT 최신 버전 및 보안 권고사항 확인
curl -s "https://search.maven.org/solrsearch/select?q=g:io.jsonwebtoken+AND+a:jjwt-api&rows=5&wt=json" | jq '.response.docs[0].latestVersion'
Length of output: 152 Script: #!/bin/bash
# Check current JJWT version in the project
fd "buildSrc|gradle.properties" --type f --exec cat {} \; | grep -i "JJWT"
# Check if BOM is already used somewhere in the project
fd "build.gradle.kts$" --type f --exec grep -l "jjwt-bom" {} \;
Length of output: 144 Script: #!/bin/bash
# Try to find Versions.kt or similar files that might contain version definitions
fd "Versions.kt" --type f --exec cat {} \;
# Look for JJWT version definition in any Kotlin or Gradle files
rg "JJWT.*=.*\".*\"" --type kotlin --type gradle
Length of output: 450 |
||
} | ||
|
||
tasks { | ||
withType<Jar> { enabled = true } | ||
withType<BootJar> { enabled = false } | ||
} | ||
Comment on lines
+9
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive) Gradle 태스크 구성에 대한 제안 태스크 구성이 잘 되어있네요! 혹시 추가로 다음과 같은 설정도 고려해보시면 어떨까요? tasks {
withType<Jar> {
enabled = true
manifest {
attributes(
"Implementation-Title" to project.name,
"Implementation-Version" to project.version
)
}
}
withType<BootJar> { enabled = false }
} 이렇게 하면 JAR 파일에 유용한 메타데이터가 포함되어 버전 관리가 더욱 수월해질 거예요! 😊 |
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,10 @@ | ||||||||||||||||||
package org.doorip.support.jwt | ||||||||||||||||||
|
||||||||||||||||||
import java.time.LocalDateTime | ||||||||||||||||||
import java.time.ZoneId | ||||||||||||||||||
import java.util.* | ||||||||||||||||||
|
||||||||||||||||||
fun LocalDateTime.toDate(): Date { | ||||||||||||||||||
val instant = this.atZone(ZoneId.systemDefault()).toInstant() | ||||||||||||||||||
return Date.from(instant) | ||||||||||||||||||
} | ||||||||||||||||||
Comment on lines
+7
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 시스템 기본 시간대 사용에 대한 고려사항 친절하게 말씀드리자면, 시스템의 기본 시간대를 사용하시는 것이 향후 문제가 될 수 있어요. 특히 여러 서버에서 실행되거나 다른 시간대의 사용자들이 있는 경우에 예기치 않은 동작이 발생할 수 있답니다. 😊 다음과 같은 개선을 제안드립니다: -fun LocalDateTime.toDate(): Date {
- val instant = this.atZone(ZoneId.systemDefault()).toInstant()
- return Date.from(instant)
+fun LocalDateTime.toDate(zoneId: ZoneId = ZoneId.of("UTC")): Date {
+ val instant = this.atZone(zoneId).toInstant()
+ return Date.from(instant)
} 이렇게 하면 다음과 같은 이점이 있어요:
📝 Committable suggestion
Suggested change
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.doorip.support.jwt | ||
|
||
import com.fasterxml.jackson.core.JsonParseException | ||
import com.fasterxml.jackson.core.type.TypeReference | ||
import com.fasterxml.jackson.databind.DatabindException | ||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import io.jsonwebtoken.Claims | ||
import io.jsonwebtoken.JwtException | ||
import io.jsonwebtoken.JwtParser | ||
import io.jsonwebtoken.Jwts | ||
import java.security.PublicKey | ||
import java.time.LocalDateTime | ||
import java.time.LocalDateTime.now | ||
import java.util.* | ||
import javax.crypto.SecretKey | ||
|
||
class JwtProvider { | ||
private val objectMapper = ObjectMapper() | ||
private val typeReference = object : TypeReference<Map<String, String>>() {} | ||
|
||
fun generate(id: String, expiration: LocalDateTime, key: SignatureKey): String { | ||
return Jwts.builder() | ||
.issuedAt(now().toDate()) | ||
.expiration(expiration.toDate()) | ||
.subject(id) | ||
.signWith(key.key) | ||
.compact() | ||
} | ||
|
||
fun validateAndGetSubject(token: String, key: SignatureKey): String? { | ||
val payload = parsePayload(token, key) ?: return null | ||
return payload.subject | ||
} | ||
|
||
fun validateAndGetSubject(token: String, key: SignatureKey, iss: String, aud: String): String? { | ||
val payload = parsePayload(token, key) ?: return null | ||
if (payload.issuer == iss && payload.audience.contains(aud)) { | ||
return payload.subject | ||
} | ||
return null | ||
} | ||
|
||
fun validateAndGetClaim(token: String, key: SignatureKey, claimName: String): String? { | ||
val payload = parsePayload(token, key) ?: return null | ||
return payload.get(claimName, String::class.java) | ||
} | ||
|
||
fun parseHeader(token: String): Map<String, String>? { | ||
try { | ||
val header = token.split(".")[0] | ||
val decoder = Base64.getUrlDecoder() | ||
val decoded = String(decoder.decode(header)) | ||
return objectMapper.readValue(decoded, typeReference) | ||
} catch (e: DatabindException) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 처리를 개선해 주세요
🧰 Tools🪛 detekt (1.23.7)[warning] 54-54: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) |
||
return null | ||
} catch (e: JsonParseException) { | ||
return null | ||
} catch (e: IndexOutOfBoundsException) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 처리를 개선해 주세요
🧰 Tools🪛 detekt (1.23.7)[warning] 58-58: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. (detekt.exceptions.TooGenericExceptionCaught) [warning] 58-58: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) 🛠️ Refactor suggestion 너무 일반적인 예외를 캡처하고 있습니다
🧰 Tools🪛 detekt (1.23.7)[warning] 58-58: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. (detekt.exceptions.TooGenericExceptionCaught) [warning] 58-58: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) |
||
return null | ||
} | ||
} | ||
|
||
private fun parsePayload(token: String, key: SignatureKey): Claims? { | ||
try { | ||
val parser = when (val signatureKey = key.key) { | ||
is SecretKey -> generateParser(signatureKey) | ||
is PublicKey -> generateParser(signatureKey) | ||
else -> return null | ||
Comment on lines
+66
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick (assertive)
|
||
} | ||
return parser.parseSignedClaims(token).payload | ||
} catch (e: JwtException) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 처리를 개선해 주세요
🧰 Tools🪛 detekt (1.23.7)[warning] 71-71: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) |
||
return null | ||
} | ||
} | ||
|
||
private fun generateParser(key: SecretKey): JwtParser { | ||
return Jwts.parser() | ||
.verifyWith(key) | ||
.build() | ||
} | ||
|
||
private fun generateParser(key: PublicKey): JwtParser { | ||
return Jwts.parser() | ||
.verifyWith(key) | ||
.build() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.doorip.support.jwt | ||
|
||
import io.jsonwebtoken.security.Keys | ||
import java.security.Key | ||
|
||
class JwtSecretKey( | ||
private val secret: String, | ||
) : SignatureKey { | ||
|
||
override val key: Key by lazy { | ||
Keys.hmacShaKeyFor(secret.toByteArray()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,34 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
package org.doorip.support.jwt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.math.BigInteger | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.security.Key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.security.KeyFactory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.security.spec.RSAPublicKeySpec | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import java.util.* | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class RSAPublicKey( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private val n: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private val e: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private val type: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) : SignatureKey { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+9
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 생성자 매개변수 유효성 검사가 필요해요! 🔍 현재 구현에서는 입력값 다음과 같이 생성자에서 유효성 검사를 추가하는 것을 추천드립니다: class RSAPublicKey(
private val n: String,
private val e: String,
private val type: String,
-) : SignatureKey {
+) : SignatureKey {
+ init {
+ require(n.isNotBlank()) { "modulus는 비어있을 수 없습니다" }
+ require(e.isNotBlank()) { "exponent는 비어있을 수 없습니다" }
+ require(type == "RSA") { "현재는 RSA 알고리즘만 지원합니다" }
+ } 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
override val key: Key? by lazy { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val decoder = Base64.getUrlDecoder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val nBytes = decoder.decode(n) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val eBytes = decoder.decode(e) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val n = BigInteger(1, nBytes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val e = BigInteger(1, eBytes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val rsaPublicKeySpec = RSAPublicKeySpec(n, e) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
val keyFactory = KeyFactory.getInstance(type) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
keyFactory.generatePublic(rsaPublicKeySpec) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: Exception) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
null | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+15
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 처리를 개선해 주세요 🛡️ 현재 구현에는 몇 가지 개선이 필요한 부분이 있어요:
다음과 같이 개선하는 것을 추천드립니다: - override val key: Key? by lazy {
+ override val key: Key by lazy {
try {
val decoder = Base64.getUrlDecoder()
val nBytes = decoder.decode(n)
val eBytes = decoder.decode(e)
val n = BigInteger(1, nBytes)
val e = BigInteger(1, eBytes)
val rsaPublicKeySpec = RSAPublicKeySpec(n, e)
val keyFactory = KeyFactory.getInstance(type)
keyFactory.generatePublic(rsaPublicKeySpec)
- } catch (e: Exception) {
- null
+ } catch (e: IllegalArgumentException) {
+ throw IllegalArgumentException("잘못된 Base64 형식입니다", e)
+ } catch (e: NoSuchAlgorithmException) {
+ throw IllegalArgumentException("지원하지 않는 알고리즘입니다: $type", e)
+ } catch (e: InvalidKeySpecException) {
+ throw IllegalArgumentException("잘못된 키 형식입니다", e)
+ } catch (e: Exception) {
+ throw IllegalStateException("공개키 생성 중 예기치 않은 오류가 발생했습니다", e)
}
} 📝 Committable suggestion
Suggested change
🧰 Tools🪛 detekt (1.23.7)[warning] 30-30: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. (detekt.exceptions.TooGenericExceptionCaught) [warning] 30-30: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. support:jwt 모듈에서 예외 클래스를 가진 domain 모듈을 의존하지 않게 하기 위함이라 예외보단 null로 관리해서 해당 key를 사용하는 클래스에서 예외 핸들링을 해주는게 맞는거 같아 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SunwoongH, 이해했습니다. (_/) ✏️ Learnings added
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,7 @@ | ||||||||||||||||||||||||||||||||
package org.doorip.support.jwt | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
import java.security.Key | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
interface SignatureKey { | ||||||||||||||||||||||||||||||||
val key: Key? | ||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||
Comment on lines
+5
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 인터페이스 설계를 개선해 주세요 🎨 안녕하세요!
다음과 같이 개선하는 것을 제안드립니다: +/**
+ * JWT 서명에 사용되는 키를 제공하는 인터페이스입니다.
+ */
interface SignatureKey {
- val key: Key?
+ val key: Key
+
+ /**
+ * 키의 유효성을 검증합니다.
+ * @throws IllegalStateException 키가 유효하지 않은 경우
+ */
+ fun validate()
} 📝 Committable suggestion
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. key가 nullable인 이유는 RSAPublicKey에서 키 생성 예외가 발생한 경우 예외를 던지지 않고 null을 저장해서 관리하기 위함이긴 해 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @SunwoongH, 이해했습니다. ✏️ Learnings added
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
toLong() 변환 시 예외 처리가 필요해 보여요 🤔
subject를 Long으로 변환하는 과정에서 NumberFormatException이 발생할 수 있습니다. 안전한 처리를 위해 예외 처리를 추가하면 좋을 것 같아요.
다음과 같은 방식으로 개선해보는 건 어떨까요?
📝 Committable suggestion