본문 바로가기

Dot Programming/Spring Clone

[스프링 웹앱 프로젝트 #11]회원 가입 완료 후 자동 로그인

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"));;

 

테스트 완료!

 

 

뷰는 다음 강의에 계속됩니다.

 


출처

인프런 강의 - 스프링과 JPA 기반 웹 애플리케이션 개발