패스워드를 잊은 경우에는 "로그인 할 수 있는 링크"를 이메일로 전송한다.
이메일로 전송된 링크를 클릭하면 로그인 한다.
GET /email-login
- 이메일을 입력할 수 있는 폼을 보여주고, 링크 전송 버튼을 제공한다.
POST /email-login
- 입력받은 이메일에 해당하는 계정을 찾아보고, 있는 계정이면 로그인 가능한 링크를 이메일로 전송한다.
- 이메일 전송 후, 안내 메시지를 보여준다.
GET /login-by-email
- 토큰과 이메일을 확인한 뒤 해당 계정으로 로그인한다.
핸들러 작성
package me.weekbelt.studyolle.account;
@RequiredArgsConstructor
@Controller
public class AccountController {
// 기존 코드 ......
@GetMapping("/email-login")
public String emailLoginForm() {
return "account/email-login";
}
@PostMapping("/email-login")
public String sendEmailLoginLink(String email, Model model, RedirectAttributes attributes) {
Account account = accountRepository.findByEmail(email);
if (account == null){
model.addAttribute("error", "유효한 이메일 주소가 아닙니다.");
return "account/email-login";
}
if(!account.canSendConfirmEmail()) {
model.addAttribute("error", "이메일 로그인은 1시간 뒤에 사용할 수 있습니다.");
return "account/email-login";
}
accountService.sendLoginLink(account);
attributes.addFlashAttribute("message", "이메일 인증 메일을 발송했습니다.");
return "redirect:/email-login";
}
@GetMapping("/login-by-email")
public String loginByEmail(String token, String email, Model model) {
Account account = accountRepository.findByEmail(email);
String view = "account/logged-in-by-email";
if (account == null || !account.isValidToken(token)) {
model.addAttribute("error", "로그인할 수 없습니다.");
return view;
}
accountService.login(account);
return view;
}
}
이메일로 로그인을 하기위한 sendLoginLink메소드 작성
package me.weekbelt.studyolle.account;
@Transactional
@RequiredArgsConstructor
@Service
public class AccountService implements UserDetailsService {
// 기존 코드 .......
public void sendLoginLink(Account account) {
account.generateEmailCheckToken();;
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(account.getEmail());
mailMessage.setSubject("스터디올래, 로그인 링크");
mailMessage.setText("/login-by-email?token=" + account.getEmailCheckToken() +
"&email=" + account.getEmail());
javaMailSender.send(mailMessage);
}
}
패스워드 없이 로그인하는 뷰를 요청할때 로그아웃상태이므로 인증이 필요없기때문에 SpringSecurity에서 WebSecurity설정에 account/email-login을 추가한다.
또한 이메일인증 요청 처리를 위한 /login-by-email의 접근을 추가한다.
package me.weekbelt.studyolle.config;
@RequiredArgsConstructor
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AccountService accountService;
private final DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
// /login-by-email 추가
http.authorizeRequests()
.mvcMatchers("/", "/login", "/sign-up", "/check-email-token", "/login-by-email",
"/email-login", "/check-email-login", "/login-link").permitAll()
.mvcMatchers(HttpMethod.GET, "/profile/*").permitAll()
.anyRequest().authenticated();
// 기존 코드 .......
;
}
// 기존 코드 ...........
// static 관련 파일들은 스프링 시큐리티 적용 x
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.mvcMatchers("account/email-login") // 추가
.mvcMatchers("/node_modules/**")
.requestMatchers(PathRequest.toStaticResources().atCommonLocations());
}
}
참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1/dashboard
인프런 - 로그인이 필요합니다
2020년 4월 21일 ~ 4월 29일 안내 글 보기 >>
www.inflearn.com
'스프링과 JPA 기반 웹 어플리케이션 개발 > 1부 (개발환경, 회원가입, 로그인, 계정설정)' 카테고리의 다른 글
30. 닉네임 수정 (0) | 2020.04.22 |
---|---|
29. ModelMapper 적용 (0) | 2020.04.22 |
28. 알림 설정 (0) | 2020.04.22 |
27. 패스워드 수정 테스트 (0) | 2020.04.22 |
26. 패스워드 수정 (0) | 2020.04.21 |