스프링과 JPA 기반 웹 애플리케이션 개발 #16 회원 가입 완료 후 자동 로그인

Jake Seo·2021년 5월 28일
0

스프링과 JPA 기반 웹 애플리케이션 개발 #16 회원 가입 완료 후 자동 로그인

해당 내용은 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발의 강의 내용을 바탕으로 작성된 내용입니다.

강의를 학습하며 요약한 내용을 출처를 표기하고 블로깅 또는 문서로 공개하는 것을 허용합니다 라는 원칙 하에 요약 내용을 공개합니다. 출처는 위에 언급되어있듯, 인프런, 스프링과 JPA 기반 웹 애플리케이션 개발입니다.

제가 학습한 소스코드는 https://github.com/n00nietzsche/jakestudy_webapp 에 지속적으로 업로드 됩니다. 매 커밋 메세지에 강의의 어디 부분까지 진행됐는지 기록해놓겠습니다.


회원 가입: 가입 완료 후 자동 로그인

  • 목표
    • 회원 가입 완료 시 자동 로그인
    • 이메일 인증 완료 시 자동 로그인
  • 스프링 시큐리티 관점에서 로그인
    • SecurityContextAuthentication(Token)이 존재하는가?
    • UsernamePasswordAuthenticationToken
    • 이메일 인증을 하지 않은 사용자의 자동 로그인은 "인증" 경고 창 보여주기
    • 이메일 인증을 마친 사용자의 자동 로그인은 깔끔하게
    • 메인 네비게이션 메뉴 변경

AccountService 클래스

login 메소드 추가

    public void login(Account account) {
        UsernamePasswordAuthenticationToken token =
                new UsernamePasswordAuthenticationToken(
                        account.getNickname(),
                        account.getPassword(),
                        List.of(new SimpleGrantedAuthority("ROLE_USER"))
                );

        SecurityContext context = SecurityContextHolder.getContext();
        context.setAuthentication(token);

        // 정석적인 방법은 아래와 같이 AuthenticationManager 를 이용해서 인증하고 Authentication 객체를 발급받는 것임
        // 정석적인 방법을 쓰려면 plain-text 형태의 패스워드가 필요해서 위의 방법을 씀
        /*
        UsernamePasswordAuthenticationToken token1 =
        new UsernamePasswordAuthenticationToken(
          account.getNickname(),
          account.getPassword()
        );
        // 주입받아야 함
        // private final AuthenticationManager authenticationManager;
        AuthenticationManager authenticationManager;
        Authentication authentication = authenticationManager.authenticate(token);
         */
    }

위와 같이 login() 메소드가 추가되었다.

  • 스프링 시큐리티의 UsernamePasswordAuthenticationToken() 객체를 생성하여 토큰을 만든다.
  • SecurityContext를 정적 메소드인 SecurityContextHolder.getContext() 메소드를 통해 불러온다.
  • 불러온 SecurityContext에서 .setAuthentication() 메소드에 token을 삽입하여 해당 토큰을 인증 정보에 넣어준다.
  • 토큰을 가진 SecurityContext는 앞으로 해당 계정이 로그인되었다고 판단한다.

서버에서 저런 로직을 통해 로그인한다면 각각 다른 유저에게 다른 스레드를 할당하는건가? 내부 동작을 좀 찾아봐야겠다.

Account 도메인

isValidToken() 메소드 추가

    public boolean isValidToken(String token) {
        return this.getEmailCheckToken().equals(token);
    }

조금 더 쉽게 읽히는 코드를 위해, .getEmailCheckToken().equals(token).isValidToken()이라는 메소드로 묶어주었다.

AccountControllerTest 클래스

인증 확인부분 추가

.andExpect(view().name("account/checked-email"))
.andExpect(authenticated().withUsername(testNickname)); // 테스트에서도 시큐리티에 의해 인증이 된 상태인지 확인할 

테스트에서도 스프링 시큐리티에 관련된 테스트를 지원하여 authenticated() 메소드로 인증이 된 상태인지 확인할 수 있고, withUsername() 으로 어떤 유저로 인증이 된 상태인지도 확인할 수 있다.

또한 unauthenticated() 메소드를 이용하면 인증이 안 된 상태인지도 확인할 수 있다.

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글