구현한 로직
- 가입 확인 이메일을 재전송할 수 있는 기능 제공
- 하지만, 너무 자주 이메일을 전송할 경우 리소스를 낭비할 수 있다는 문제가 있음
- 보완책으로, 1시간에 한 번만 인증 메일을 전송할 수 있도록 제한한다.
GET "/check-email"
- 가입 확인 이메일을 전송한 이메일 주소(== 가입할 때 입력한 이메일 주소)를 화면에 보여줌.
- 재전송 버튼 보여주기.
- 재전송 버튼 클릭하면 GET "/resend-confirm-email" 요청 전송
GET "/resend-confirm-email"
- 인증 메일을 다시 전송할 수 있는지 확인한 뒤에
- 보낼 수 있으면 전송하고, 첫 페이지로 리다이렉트
- 보낼 수 없으면 에러 메시지를 모델에 담아주고 이메일 확인 페이지 다시 보여주기
SecurityConfig 설정 수정
package me.weekbelt.studyolle.config;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// "check-email" 제거 (로그인 한 사용자에만 접근해야 하기 때문)
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/", "/login", "/sign-up", "/check-email-token",
"/email-login", "/check-email-login", "/login-link").permitAll()
.mvcMatchers(HttpMethod.GET, "/profile/*").permitAll()
.anyRequest().authenticated();
;
}
// 기존 코드 .......
}
AccountController에 checkEmail메소드 추가
ㅁpackage me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Controller
public class AccountController {
// 기존 코드 ..........
// 추가
@GetMapping("/check-email")
public String checkEmail(@CurrentUser Account account, Model model) {
model.addAttribute("email", account.getEmail());
return "account/check-email";
}
}
이메일 인증을 보내기 위한 페이지인 /account/check-email.html 작성
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="fragments.html::head"></head>
<body class="bg-light">
<!--네비게이션 바-->
<div th:replace="fragments.html::main-nav"></div>
<div class="container">
<!--에러메시지가 있을경우-->
<div class="py-5 text-center" th:if="${error != null}">
<p class="lead">스터디올래 가입</p>
<div class="alert alert-danger" role="alert"th:text="${error}"></div>
<p class="lead" th:text="${email}">your@email.com</p>
</div>
<!--에러메시지가 없을 경우-->
<div class="py-5 text-center" th:if="${error == null}">
<p class="lead">스터디올래 가입</p>
<h2>스터디올래 서비스를 사용하려면 인증 이메일을 확인하세요.</h2>
<div>
<p class="lead" th:text="${email}">your@email.com</p>
<a class="btn btn-outline-info" th:href="@{/resend-confirm-email}">인증 이메일 다시 보내기</a>
</div>
</div>
</div>
<!-- footer -->
<div th:replace="fragments.html::footer"></div>
</body>
</html>
이메일 인증 요청을 처리하는 핸들러 메소드를 AccountController에 구현
package me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Controller
public class AccountController {
// 기존 코드 ......
@GetMapping("/resend-confirm-email")
public String resendConfirmEmail(@CurrentUser Account account, Model model){
if (!account.canSendConfirmEmail()){
model.addAttribute("error", "인증 이메일은 1시간에 한번만 전송할 수 있습니다.");
model.addAttribute("email", account.getEmail());
return "account/check-email";
}
accountService.sendSignUpConfirmEmail(account);
return "redirect:/";
}
}
Account엔티티에 이메일 토큰을 발행한지 1시간이 지났는지 아닌지 확인하는 코드 추가
package me.weekbelt.studyolle.domain;
@Builder @AllArgsConstructor @NoArgsConstructor
@Getter @Setter @EqualsAndHashCode(of = "id")
@Entity
public class Account {
// 기존 코드 .........
private LocalDateTime emailCheckTokenGeneratedAt; // 토큰 발행 시간 필드 추가
public void generateEmailCheckToken() {
this.emailCheckToken = UUID.randomUUID().toString();
this.emailCheckTokenGeneratedAt = LocalDateTime.now(); // 추가
}
// 기존 코드 .........
// 추가
public boolean canSendConfirmEmail() {
return this.emailCheckTokenGeneratedAt.isBefore(LocalDateTime.now().minusHours(1));
}
}
AccountService의 sendSignUpConfirmEmail() 메소드를 private에서 public으로 접근 제한 수정
package me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Service
public class AccountService {
// 기존코드 ....
public void sendSignUpConfirmEmail(Account newAccount) { //public으로 수정
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(newAccount.getEmail());
mailMessage.setSubject("스터디올래, 회원 가입 인증");
mailMessage.setText("/check-email-token?token=" + newAccount.getEmailCheckToken() + "&email=" + newAccount.getEmail());
javaMailSender.send(mailMessage);
}
// 기존코드 ......
}
참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#
스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런
이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습니다. 이 강좌를 충분히 학습한다면 여러분 만의 웹 서비스를 만들거나 취직에 도움이 될만한 포트폴리오를 만들 수 있을 겁니다. 활용 웹 개발 프레임워크 및 라이브러리 Java Spring Spring Boot Spring Data JPA Thymeleaf 온라인 강의 스
www.inflearn.com
'스프링과 JPA 기반 웹 어플리케이션 개발 > 1부 (개발환경, 회원가입, 로그인, 계정설정)' 카테고리의 다른 글
18. 로그인 / 로그아웃 테스트 (0) | 2020.04.20 |
---|---|
17. 로그인 / 로그아웃 (0) | 2020.04.20 |
15. 현재 인증된 사용자 정보 참조 (0) | 2020.04.20 |
14. 첫 페이지 보완 (0) | 2020.04.20 |
13. 뷰 중복 코드 제거 (0) | 2020.04.19 |