Skip to content

Commit a08799b

Browse files
authored
feat: 이메일 인증 예외처리 개선 (#242)
* chore: 불필요한 swagger 삭제 * feat: 인증코드 만료 예외 처리 추가 * refactor: 유저 생성 로직 UserService로 이동 * chore: .DS_Store 삭제 * chore: 인증 실패시 로깅 추가
1 parent 0db5aca commit a08799b

File tree

7 files changed

+29
-52
lines changed

7 files changed

+29
-52
lines changed

.DS_Store

-10 KB
Binary file not shown.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ build/
33
!gradle/wrapper/gradle-wrapper.jar
44
!**/src/main/**/build/
55
!**/src/test/**/build/
6-
.DS_store
6+
.DS_Store
77

88
### STS ###
99
.apt_generated

src/main/kotlin/uoslife/servermeeting/global/error/exception/ErrorCode.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ enum class ErrorCode(val code: String, val message: String, var status: Int) {
137137
HttpStatus.TOO_MANY_REQUESTS.value()
138138
),
139139
EMAIL_SEND_FAILED("E06", "Failed to send email.", HttpStatus.INTERNAL_SERVER_ERROR.value()),
140+
EMAIL_VERIFICATION_CODE_EXPIRED("E06", "인증 코드가 만료되었습니다.", HttpStatus.BAD_REQUEST.value()),
140141

141142
// JWT
142143
JWT_TOKEN_NOT_FOUND("J001", "Token not found", HttpStatus.UNAUTHORIZED.value()),

src/main/kotlin/uoslife/servermeeting/user/service/UserService.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,13 @@ class UserService(
245245
}
246246
return TeamBranch.JOINED
247247
}
248+
249+
@Transactional
250+
fun getOrCreateUser(email: String): User {
251+
return try {
252+
getUserByEmail(email)
253+
} catch (e: UserNotFoundException) {
254+
createUserByEmail(email)
255+
}
256+
}
248257
}

src/main/kotlin/uoslife/servermeeting/verification/api/VerificationApi.kt

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -140,47 +140,7 @@ class VerificationApi(
140140
)]
141141
)]
142142
),
143-
ApiResponse(
144-
responseCode = "401",
145-
description = "인증 오류",
146-
content =
147-
[
148-
Content(
149-
schema = Schema(implementation = ErrorResponse::class),
150-
examples =
151-
[
152-
ExampleObject(
153-
name = "Token Not Found",
154-
value =
155-
"{\"message\": \"Token not found\", \"status\": 401, \"code\": \"J001\"}"
156-
),
157-
ExampleObject(
158-
name = "Token Expired",
159-
value =
160-
"{\"message\": \"Token has expired\", \"status\": 401, \"code\": \"J002\"}"
161-
),
162-
ExampleObject(
163-
name = "Invalid Token Format",
164-
value =
165-
"{\"message\": \"Invalid token format\", \"status\": 401, \"code\": \"J003\"}"
166-
),
167-
ExampleObject(
168-
name = "Invalid Token Signature",
169-
value =
170-
"{\"message\": \"Invalid token signature\", \"status\": 401, \"code\": \"J004\"}"
171-
),
172-
ExampleObject(
173-
name = "Refresh Token Not Found",
174-
value =
175-
"{\"message\": \"Refresh token not found\", \"status\": 401, \"code\": \"J005\"}"
176-
),
177-
ExampleObject(
178-
name = "Refresh Token Expired",
179-
value =
180-
"{\"message\": \"Refresh token has expired\", \"status\": 401, \"code\": \"J006\"}"
181-
)]
182-
)]
183-
)]
143+
]
184144
)
185145
// TODO: Service layer로 이동해야함
186146
@PostMapping("/verify-email")
@@ -192,12 +152,7 @@ class VerificationApi(
192152
val requestInfo = requestUtils.toRequestInfoDto(request)
193153
emailVerificationService.verifyEmail(body.email, body.code, requestInfo)
194154

195-
val user =
196-
try {
197-
userService.getUserByEmail(body.email)
198-
} catch (e: Exception) {
199-
userService.createUserByEmail(body.email)
200-
}
155+
val user = userService.getOrCreateUser(body.email)
201156

202157
val accessToken = authService.issueTokens(user.id!!, response)
203158
return ResponseEntity.ok(accessToken)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package uoslife.servermeeting.verification.exception
2+
3+
import uoslife.servermeeting.global.error.exception.BusinessException
4+
import uoslife.servermeeting.global.error.exception.ErrorCode
5+
6+
class EmailVerificationCodeExpiredException :
7+
BusinessException(ErrorCode.EMAIL_VERIFICATION_CODE_EXPIRED) {}

src/main/kotlin/uoslife/servermeeting/verification/service/EmailVerificationService.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,22 @@ class EmailVerificationService(
5555
validateVerificationAttempts(email)
5656
incrementVerificationAttempts(email)
5757
// Redis에서 인증 코드 조회
58-
val redisCode = getVerificationCode(email)
58+
val redisCode = getVerificationCode(email, requestInfo)
5959
// 인증 코드 검증
6060
validateVerificationCode(redisCode, code, email, requestInfo)
6161
// 검증 성공한 코드 삭제
6262
clearVerificationData(email)
6363
}
6464

65-
private fun getVerificationCode(email: String): String {
65+
private fun getVerificationCode(email: String, requestInfo: RequestInfoDto): String {
6666
val verificationCodeKey =
6767
VerificationUtils.generateRedisKey(VerificationConstants.CODE_PREFIX, email)
68-
return redisTemplate.opsForValue().get(verificationCodeKey).toString()
68+
val code = redisTemplate.opsForValue().get(verificationCodeKey)
69+
if (code == null) {
70+
logger.warn("[이메일 인증 실패(만료)] email: $email, $requestInfo")
71+
throw EmailVerificationCodeExpiredException()
72+
}
73+
return code.toString()
6974
}
7075

7176
private fun validateVerificationCode(
@@ -75,7 +80,7 @@ class EmailVerificationService(
7580
requestInfo: RequestInfoDto
7681
) {
7782
if (redisCode != code) {
78-
logger.warn("[이메일 인증 실패] email: $email, $requestInfo")
83+
logger.warn("[이메일 인증 실패(불일치)] email: $email, $requestInfo")
7984
throw EmailVerificationCodeMismatchException()
8085
}
8186
logger.info("[이메일 인증 성공] email: $email")

0 commit comments

Comments
 (0)