-
Notifications
You must be signed in to change notification settings - Fork 2
[BE] 이메일 전송 및 인증로직 추가 #79
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
The head ref may contain hidden characters: "SISC1-20251104-\uC774\uBA54\uC77C\uC778\uC99D\uAE30\uB2A5\uCD94\uAC00"
Conversation
Walkthrough이 PR은 이메일 인증 기능을 추가합니다: 구성 프로퍼티, REST 엔드포인트(/api/email/send, /api/email/verify), EmailService 구현(코드 생성/저장/검증, Thymeleaf 이메일 전송), Redis 상태 관리, 에러 코드 추가, 템플릿, 단위테스트 및 빌드 의존성 확장. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant EmailController
participant EmailService
participant Redis
participant TemplateEngine
participant MailSender
Client->>EmailController: POST /api/email/send?email=...
EmailController->>EmailService: sendEmail(email)
rect rgb(245,250,255)
Note over EmailService,Redis: 사전검증(verified 조회, 이메일 형식/중복 확인)
EmailService->>Redis: GET verified:{email}
EmailService->>EmailService: validate email, check user
end
rect rgb(230,255,235)
Note over EmailService: 코드 생성 및 전송
EmailService->>EmailService: generateCode()
EmailService->>Redis: SET verify:{email} = code (TTL)
EmailService->>TemplateEngine: render(mail/verificationEmail, vars)
EmailService->>MailSender: send(MimeMessage)
end
MailSender-->>EmailService: send result
EmailService-->>EmailController: success
EmailController-->>Client: 200 OK
Client->>EmailController: POST /api/email/verify?email=...&code=...
EmailController->>EmailService: verifyEmail(email, code)
rect rgb(255,240,240)
Note over EmailService,Redis: 코드 검증 및 상태 변경
EmailService->>Redis: GET verify:{email}
EmailService->>EmailService: compare codes
EmailService->>Redis: DEL verify:{email}
EmailService->>Redis: SET verified:{email} = true (TTL 24h)
end
EmailService-->>EmailController: success
EmailController-->>Client: 200 OK
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 3
🧹 Nitpick comments (2)
backend/src/main/resources/templates/mail/verificationEmail.html (1)
67-69: 인증 유효시간을 하드코딩하면 설정과 불일치할 수 있습니다본문에 “3분”이 고정 표기되어 있는데, 실제 만료 시간은
EmailProperties.codeExpire설정값에 따라 달라집니다. 설정이 바뀌면 사용자에게 잘못된 안내가 전달되므로, 컨텍스트에 만료 분(또는 시각)을 넣어 템플릿에서 동적으로 렌더링하도록 바꿔 주세요.backend/src/test/java/org/sejongisc/backend/auth/service/EmailServiceTest.java (1)
85-87: 빈 테스트 케이스는 의미 있는 검증을 제공하지 않습니다
verifyEmail()테스트가 비어 있어 아무 검증도 수행하지 않습니다. 실제 시나리오(코드 불일치, 만료, 성공 등)를 검증하도록 구현하거나 불필요하다면 제거해 주세요.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
backend/build.gradle(2 hunks)backend/src/main/java/org/sejongisc/backend/auth/config/EmailProperties.java(1 hunks)backend/src/main/java/org/sejongisc/backend/auth/controller/EmailController.java(1 hunks)backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java(1 hunks)backend/src/main/java/org/sejongisc/backend/common/auth/config/SecurityConfig.java(1 hunks)backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java(1 hunks)backend/src/main/resources/templates/mail/verificationEmail.html(1 hunks)backend/src/test/java/org/sejongisc/backend/auth/service/EmailServiceTest.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java (2)
backend/src/main/java/org/sejongisc/backend/common/exception/CustomException.java (1)
Getter(5-14)backend/src/main/java/org/sejongisc/backend/common/exception/ErrorResponse.java (1)
Getter(7-21)
backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java (1)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1)
Override(34-69)
backend/src/main/java/org/sejongisc/backend/auth/config/EmailProperties.java (1)
backend/src/main/java/org/sejongisc/backend/common/auth/config/SecurityConfig.java (1)
Configuration(23-88)
backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java
Outdated
Show resolved
Hide resolved
backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java
Outdated
Show resolved
Hide resolved
discipline24
left a comment
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.
깔끔하네요 고생하셨습니다!
backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java
Show resolved
Hide resolved
backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java
Show resolved
Hide resolved
validator이나 비동기제거(인증이메일에 불필요) 에러코드 수정등 자잘한 수정
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.
Actionable comments posted: 1
🧹 Nitpick comments (4)
backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java (1)
53-57: 에러 메시지 마침표 일관성 확보 필요일부 에러 메시지는 마침표로 끝나고(
EMAIL_CODE_MISMATCH,EMAIL_ALREADY_VERIFIED) 일부는 마침표가 없습니다(EMAIL_CODE_NOT_FOUND,EMAIL_INVALID_EMAIL). 기존 에러 코드들과의 일관성을 위해 모든 메시지를 마침표로 통일해 주세요.- EMAIL_CODE_NOT_FOUND(HttpStatus.NOT_FOUND, "이메일 인증 코드를 찾을 수 없습니다"), + EMAIL_CODE_NOT_FOUND(HttpStatus.NOT_FOUND, "이메일 인증 코드를 찾을 수 없습니다."), EMAIL_CODE_MISMATCH(HttpStatus.BAD_REQUEST, "인증 코드가 일치하지 않습니다."), - EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다"), + EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다."), EMAIL_ALREADY_VERIFIED(HttpStatus.BAD_REQUEST, "24시간 이내에 이미 인증된 이메일입니다."),backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java (3)
64-82: Redis 작업 간 경쟁 조건 가능성
hasKey체크(Line 64)와 인증 코드 저장(Line 82) 사이에 다른 요청이 끼어들 수 있어, 동일한 이메일에 대해 여러 인증 메일이 동시에 발송될 수 있습니다. 심각한 문제는 아니지만, Redis의SETNX명령이나 Lua 스크립트를 사용해 원자적으로 처리하면 더 견고해집니다.예시:
setIfAbsent를 활용한 원자적 처리// 인증코드 생성 - String code = generateCode(); + String code = generateCode(); + String verifyKey = emailProperties.getKeyPrefix().getVerify() + email; // Redis에 인증 코드 저장 (유효시간: 3분) - redisTemplate.opsForValue().set(emailProperties.getKeyPrefix().getVerify() + email, code, emailProperties.getCodeExpire()); + Boolean wasSet = redisTemplate.opsForValue().setIfAbsent(verifyKey, code, emailProperties.getCodeExpire()); + if (Boolean.FALSE.equals(wasSet)) { + // 이미 진행 중인 인증이 있음 - 재전송 대기 등의 로직 추가 가능 + log.info("인증 코드가 이미 존재합니다: {}", email); + }
79-79: 들여쓰기 정리불필요한 들여쓰기가 있습니다.
- // 인증코드 생성 - String code = generateCode(); + // 인증코드 생성 + String code = generateCode();
97-97: 코드 포맷팅 수정
getVerify()뒤에 공백이 누락되었습니다.- String key = emailProperties.getKeyPrefix().getVerify()+ email; + String key = emailProperties.getKeyPrefix().getVerify() + email;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
backend/build.gradle(2 hunks)backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java(1 hunks)backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java(1 hunks)
🔇 Additional comments (3)
backend/build.gradle (1)
50-82: 의존성 추가가 적절합니다.이메일 인증 기능 구현에 필요한 의존성들이 올바르게 추가되었습니다. 특히
commons-validator:1.10.0으로 업데이트하여 이전 리뷰에서 지적된 보안 취약점(CVE-2025-48734)이 해결되었습니다.backend/src/main/java/org/sejongisc/backend/auth/service/EmailService.java (2)
42-57: LGTM!Thymeleaf를 활용한 HTML 이메일 생성 로직이 올바르게 구현되었습니다.
118-129: LGTM!
SecureRandom을 사용한 안전한 인증 코드 생성 로직입니다.
#78
Summary by CodeRabbit
새로운 기능
버그 수정
테스트