구글로그인 (Oauth 20) 연결하기

구글로그인 (Oauth 20) 연결하기

로그인. 보안이 중요한 부분임 직접 구현 할 수도 있으나 세션과 쿠키처리등 복잡함 좀. 해서 검증된 모듈을 쓸 필요가 있음 PassPort 를 쓰는것 근데 이게 뭔데? 최근 동안 SNS로그인도 하는데? 카카오나 구글 네이버 페북 등 이전 있는걸로도 로그인 되잖음? 그런것도 이 설치 하면 준비 끝 세션에 불필요한 데이터는 담지 않기위해서 이렇게 합니다.

지금까지 클래스의 단위로 잘 만들어둔 것 같다. 그럼 이걸 어떻게 합쳐서 시큐리티에 적용할 수 있을까? 이런 식으로 진행하게 됩니다. 이곳에서 로그인에 대한 얘기를 하게 되는데 하지만 우리는 filter에 Manager가 있고 성공과 실패 handler 가 있습니다. 그리고 저희가 적용할 필터를 객체로 불러주어서 Bean으로 등록해주어야 합니다. 매니저는 이런 식으로 등록하게 됩니다. Manager를 Bean으로 등록을 하게 되고 매니저 안에 Provider 설정을 이렇게 해줄 수도 있습니다.

시큐리티에서 사용하는 기본적으로 로그인을 담당하는 provider인 Dao 프로바이더를 불러와서 set을 통해 사용하는 passwordEncoder를 정해주고, UserDetailsService를 저희가 만든 Custom으로 설정해 주었다.


DB 접근 기술 JdbcTemplate
DB 접근 기술 JdbcTemplate

DB 접근 기술 JdbcTemplate

현재 프로젝트는 JdbcTemplate을 사용해 리포지토리를 구성했다. 추후 MyBatis, JPA 기술로 변경할 가능성을 염두해 MemberRepository 인터페이스를 상속받는 것을 보장하도록 만들었다. 실제로 MemberService에도 JdbcTemplateMemberRepository가 아닌 MemberRepository 인터페이스에 신뢰하는 모습을 볼 있습니다.

LoginSuccessHandler
LoginSuccessHandler

LoginSuccessHandler

로그인이 인증된 코드를 들고 Authentication이 Context에 저장되었습니다. 그럼 이제 위에서 말했던 Successhandler 가 실행되어야 합니다.

이곳에서 Service에서 만든 토큰을 전달하게 되는데 하지만 accessToken과 RefreshToken을 만들어서 전달합니다. 이같은 경우애 extractUsername을 통해 인증된 Authentication 객체에서 UserDetails 객체로 옮겨 담아 거기에 있는 내용을 빼낸다.

그래서 그곳의 아이디를 가져와서 아이디를 accessToken에 넣어둔다. 그리고 마지막으로 회원이 탈퇴한 회원인지 확인하는 조건문을 넣게 되면서 탈퇴한 회원도 다뤄보고자 했다.

FailureHandler

성공을 다뤘다면 이번엔 실패를 다뤄보도록 하자 인증을 실패했다는 전제입니다.

이렇게 만약 로그인에 실패를 했다면 SimpleUrlAuthenticationFailureHandler를 상속받아 실패 메서드를 다뤘고 응답을 꾸며서 보냈다. 실패의 메소드 자체는 아주 간단했다. 그냥 서버에서 실패한 내용을 클라이언트에게 어떻게 전달할 것인가가 중요한 내용이었다.

LoginService

UserDetailService를 상속받으면, loadUserByname이 오버라이딩 해야합니다. 기본 틀 입니다. 다음은 완성 코드입니다. 이곳에서 제가 회원 엔티티를 User로 하지 않고, Member로 설정한 이유가 나옵니다. UserDetail의 User와 헷갈리기 때문이죠. 이전 시큐리티 학습 때 User로 하는 것 같았다 헷갈린 적이 있어서 맨 위의 import를 보고, 어떤 User가 import 됐나 확인했던 경험이 있습니다.

따라서 이번은 Member로 했습니다. MySQL도 User로 하면 에러남 다음은 SecurityConfig를 수정할 겁니다.

UserDetailService

서버의 입장에서 시작해보자 원초적으로 우리는 우리 서버 DB에 있는 사용자와 비교해서 인증을 확인해 주는 것이 중요합니다. 그럼 찾는 유저의 정보를 담아주는 곳이 필요한데 Security는 User라는 객체를 만들어 주어서 비교를 할 수 있게 만들어줍니다. 그럼 우린 DB에서 값을 가져와서 User 객체에 담아주면 되는 것입니다.

저희가 받아오는 사용자의 이름을 통해 DB에서 정보를 가져와서 혹시 없습니다.면 예외를 일어나고 있다면야 User 객체에 Builder를 통해 이름과 패스워드 그리고 권한까지 모두 설정하여 보낸다.

그리고 이것은 Provider 로서의 역할을 하게 될 것입니다.

입출력 예 설명

입출력 예 1

db에 같은 정보의 계정이 있으므로 login을 return합니다.

입출력 예 #2

db에 아이디는 같지만 패스워드가 다른 계정이 있으므로 “wrong pw”를 return합니다. 입출력 예 3

db에 아이디가 맞는 계정이 없으므로 fail을 return합니다. 이번 사안은 직관적이고 2차 배열의 첫 원소를 탐색하는 것이 전부이기에 오래걸리지 않았습니다.

자주 묻는 질문

DB 접근 기술

현재 프로젝트는 JdbcTemplate을 사용해 리포지토리를 구성했다. 궁금한 내용은 본문을 참고하시기 바랍니다.

로그인이 인증된 코드를 들고 Authentication이 Context에 저장되었습니다. 자세한 내용은 본문을 참고하시기 바랍니다.

FailureHandler

성공을 다뤘다면 이번엔 실패를 다뤄보도록 하자 인증을 실패했다는 전제입니다. 궁금한 사항은 본문을 참고하시기 바랍니다.