7-3. Login 커스텀

khs·2022년 3월 21일
0

Java Spring Boot

목록 보기
30/34
post-custom-banner

7-2에서 진행한 프로젝트에서 이어서 진행해보자.

먼저 WebSecurityConfig.java에서 원시 암호를 인코딩해주는 메소드를 추가한다.

그리고 실제 사용자 관리를 정의하기 위해 7-2에서와 마찬가지로 configure 메소드를 오버라이드 한 후 아래와 같이 코드를 작성한다. 유저와 관리자를 하나씩 추가했다.

그리고 프로젝트를 실행해보면 로그인이 잘 되는 것을 확인할 수 있다.

기본적으로 AuthenticationManager를 만들어주는 AuthenticationManagerBuilder auth 객체를 활용해서 사용자 관리를 하는 부분을 작성한 것이다.

inMemoryAuthentication() 메소드를 확인해보면 InMemoryUserDetailsManagerConfigurer 객체를 반환하게 되는데 InMemoryUserDetailsManagerConfigurer가 마지막으로 결과적으로 하는 것은 InMemoryUserDetailsManager라는 객체를 만들어서 반환하는 것이다.


InMemoryUserDetailsManager는 UserDetailsManager 라는 인터페이스의 구현체이고 UserDetailsManager는 UserDetailsService 라는 인터페이스를 상속받은 인터페이스이다.


결론적으로 스프링 security 에서 데이터베이스나 다른 기타 도구를 이용해서 사용자의 정보를 저장하고 싶으면 UserDetailsService를 구현한 객체를 사용해서 값을 넘겨주면 된다.

먼저 user객체를 만들어보자. entity 패키지를 만들고 그 안에 UserEntity.java를 아래와 같이 작성한다. Getter/Setter도 함께 만든다.

그리고 레포지토리 인터페이스도 만들고 service에서 사용할 메소드도 적어준다.

그 다음 infra의 이름으로 패키지를 만든 후 그 안에 아래와 같이 클래스를 작성한다.

그런데 27번째 줄에서 이를 비밀번호를 설정할 때 이를 단순한 평문으로 입력하면 안된다. 따라서 암호화를 진행해야 한다.
PasswordEncoder를 주입해주고(24번째 줄) 이를 사용한다.(30번째 줄)

그리고 WebSecurityConfig.java를 수정한다. 일단 28~35번째 줄을 다 주석처리하고 UserDetailService 객체를 만들고 생성자를 통해 이를 주입한다. 그리고 주입한 userDetailsService를 auth에 주입해준다. (26번째 줄)

이렇게 되면 오류가 뜬다. 왜냐하면 CustomUserDetailService.java와 WebSecurityConfig.java에서 동시에 PasswordEncoder를 사용하고 있기 때문이다.

CustomUserDetailService안에 있는 PasswordEncoder는 WebSecurityConfig라는 빈이 생성되는 것을 기다리고 있는데 WebSecurityConfig 빈 역시 PasswordEncoder 빈이 존재하는 WebSecurityConfig를 기다리고 있기 때문에 생기는 문제이다.
=> 서로서로를 참조하고 있다.

따라서 WebSecurityConfig.java 안에 있는 passwordEncoder()메소드를 제거하고 config 패키지 안에 패스워드를 인코드 해주는 클래스를 작성한다.

그리고 프로젝트를 실행해보면 입력했던 아이디, 비밀번호로 로그인이 잘 되는 것을 알 수 있다.

이제 회원가입 부분만 작성을 해보고 마무리하자. 먼저 회원가입 폼을 띄워주도록 controller를 작성하고 이에 해당하는 signup-form.html도 작성해준다.

그리고 홈페이지 페이지에서 위 회원가입 페이지에 들어갈 수 있도록 index.html에 버튼을 하나 만들어준다.

그리고 로그인 상태가 아니어도 해당 페이지에 접속할 수 있도록 WebSecurityConfig.java 부분도 수정을 한다. (41번째 줄 수정)

그렇다면 로그인 하지 않은 상태여도 회원가입 페이지에 접근할 수 있다. 이제 실제 회원가입 기능이 이뤄지도록 코드를 작성해보자.

먼저 Dto패키지를 만들고 그 안에 UserDto.java를 작성한다. Getter/Setter, toString도 같이 만들어준다.

그리고 UserController.java에서 Post로 전달 받을 경우에 대한 코드를 작성한다. 일단 생성자를 통해 UserRepositort를 주입받고

아래와 같이 PostMapping에 해당하는 메소드를 작성한다. PasswordEncode 부분 신경쓰는 것을 잊지말자.

그리고 프로젝트를 실행해보면 회원가입이 제대로 된 것을 확인할 수 있다.

** 추가적인 기능

첫번째 방법

HomeController.java에 home()메소드 수정

Principal를 인자로 넣어주게 되면 로그인을 한 대상을 확인할 수 있도록 해준다. (Principal 대신 Authentication 을 사용해도 된다.)

처음 페이지에 접근하게 되면 콘솔창에 아래와 같이 뜨게 되고

로그인을 하면 (아이디는 entity_user로 로그인) 아래와 같이 뜨는 것을 확인할 수 있다.

두번째 방법

흥미로운 것은 위와 같이 입력하면 로그인하지 않은 상태일 때 NullpointerExeption에 걸리는 것이 아니라 아래와 같이 뜨는 것을 확인할 수 있다.

이를 모든 클래스에서 사용하려면 아래와 같이 클래스를 따로 정의를 하고

사용하고자 하는 클래스에 주입을 해준 뒤

코드에서 사용하면 된다. 코드가 깔끔해졌다. 다른 클래스에서 usrename을 확인하기 쉬워졌다.

profile
권혁상입니다. 행복코딩^_^
post-custom-banner

0개의 댓글