12. 회원 가입 : 가입 완료 후 자동 로그인
목표
> 회원 가입 완료시 자동 로그인
> 이메일 인증 완료시 자동 로그인
스프링 시큐리티 관점에서 로그인
> SecurityContext에 Authentication(Token)이 존재하는가?
> UsernamePasswordAuthenticationToken
뷰
> 이메일 인증을 하지 않은 사용자의 자동 로그인은 "인증" 경고 창 보여주기
> 이메일 인증을 마친 사용자의 자동 로그인 깔끔!
> 메인 네비게이션 메뉴의 변경
이메일 체크 토큰 간단 리팩토링
//AccountController.class
public String checkEmailToken(String token, String email, Model model){
!account.getEmailCheckToken().equals(token)
>>
!account.isValidToken(token)
}
//Account.class
public boolean isValidToken(String token) {
return this.emailCheckToken.equals(token);
}
자동 로그인
AccountService.class
public void login(Account account) {
// 원래 AuthenticationManager내부에서 사용하는 생성자
// 정석정인 방법이 아닌 아래와 같이 코딩한 이유는 현재 인코딩한 패스워드밖에 접근하지 못하기 때문
// 정석적인 방법인 플레인 텍스트로 받은 pw를 써야하는데 현재 db에 저장도 안하고 쓸 일도 없기 때문
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
account.getNickname(),
account.getPassword(),
List.of(new SimpleGrantedAuthority("ROLE_USER")));
SecurityContextHolder.getContext().setAuthentication(token);
/**
* 원래 정석적인 방법
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
username, passsword);
Authentication authentication = authenticationManager.authenticate(token);
SecurityContext context = SecurityContextHolder.getContext();
context.setAuthentication(authentication);
*/
}
AccountController.class
@PostMapping("/sign-up")
public String signUpSubmit(@Valid SignUpForm signUpForm, Errors errors){
if (errors.hasErrors()){
return "account/sign-up";
}
Account account = accountService.processNewAccount(signUpForm);
accountService.login(account); //회원가입 후 자동 로그인
return "redirect:/";
}
@GetMapping("/check-email-token")
public String checkEmailToken(String token, String email, Model model){
Account account = accountRepository.findByEmail(email);
String view = "account/checked-email";
if(account == null) {
model.addAttribute("error", "wrong.email");
return view;
}
if(!account.isValidToken(token)){
model.addAttribute("error", "wrong.token");
return view;
}
account.completeSignUp();
accountService.login(account); //이메일 인증 후 자동 로그인
model.addAttribute("numberOfUser", accountRepository.count());
model.addAttribute("nickname", account.getNickname());
return view;
}
테스트 코드 작성
AccountControllerTest.class
//securityMockMvc에서만 제공하는 기능!
//오류 값에 추가
.andExpect(unauthenticated());
//정상 값에 추가
.andExpect(authenticated().withUsername("loosie"));;
테스트 완료!
뷰는 다음 강의에 계속됩니다.
출처
'Dot Programming > Spring Clone' 카테고리의 다른 글
[스프링 웹앱 프로젝트 #13] 프론트엔드 라이브러리 설정 (0) | 2020.11.27 |
---|---|
[스프링 웹앱 프로젝트 #12] 회원 가입 메인 네비게이션 메뉴 (0) | 2020.11.27 |
[스프링 웹앱 프로젝트 #10]회원 가입 인증 메일 확인 테스트 및 리팩토링 (0) | 2020.11.19 |
[스프링 웹앱 프로젝트 #9]회원 가입 인증 메일 확인 (0) | 2020.11.19 |
[스프링 웹앱 프로젝트 #8]회원 가입 패스워드 인코딩 (0) | 2020.11.19 |