Search

27. 스프링부트 포토그램 인증 로그인 완료

포토그램 인증 구현하기

로그인구현

회원전보 수정 구현

PrincipalDetailsService.java에 loadUserByUsername함수를 꾸며줘야하는데
password는 필요없어도 되는게 시큐리티가 알아서 비교해주기 때문에 username 만 있어도 충분하다.
username가 있는지 없는지 확인할라면 UserRepository가 필요하다.
@RequiredArgsConstructor @Service public class PrincipalDetailsService implements UserDetailsService{ private final UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { return null; } }
Java
복사
UserRepository.java에서 JPA query method 를 사용할거다.
JpaRepository라는게 유저테이블에 있는 모든 데이터를 들고와라
등등 PagingAndSortingRepository를 또 타고 들어가면 save를 통해 insert 할 수 있고 삭제할 수 있다. 하지만 제한적이라는 것
그래서 밑에 사이트 접속해서 Query Creation 검색해서 찾아보면
를 보면서 사용하면
public interface UserRepository extends JpaRepository<User, Integer>{ //JPA query method User findByUsername(String username); }
Java
복사
username을 찾아서 user오브젝트로 리턴해준다
PrincipalDetailsService.java
// 1. 패스워드는 알아서 체킹하니까 신경쓸 필요가 없다. // 2. 리턴이 잘되면 자동으로 세션을 만든다. @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User userEntity = userRepository.findByUsername(username); if(userEntity == null) { return null; }else { return userEntity; } }
Java
복사
하지만 이렇게 진행하면 return 타입이랑 리턴해주는 타입이 안맞아서 오류난다.
userEntity를 UserDetails타입으로 바꿔줘야하는데 new를 진행해서 하면 더 복잡해지기 때문에 우선은 null로 바꿔주고 진행하고 auth 폴더안에 PrincipalDetails.java 생성
package com.cos.photogramstart.config.auth; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; public class PrincipalDetails implements UserDetails{ private static final long serialVersionUID = 1L; @Override public Collection<? extends GrantedAuthority> getAuthorities() { // TODO Auto-generated method stub return null; } @Override public String getPassword() { // TODO Auto-generated method stub return null; } @Override public String getUsername() { // TODO Auto-generated method stub return null; } @Override public boolean isAccountNonExpired() { // TODO Auto-generated method stub return false; } @Override public boolean isAccountNonLocked() { // TODO Auto-generated method stub return false; } @Override public boolean isCredentialsNonExpired() { // TODO Auto-generated method stub return false; } @Override public boolean isEnabled() { // TODO Auto-generated method stub return false; } }
Java
복사
얘를 리턴시키도록 하자.
PrincipalDetailsService.java
package com.cos.photogramstart.config.auth; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import com.cos.photogramstart.domain.user.User; import com.cos.photogramstart.domain.user.UserRepository; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Service public class PrincipalDetailsService implements UserDetailsService{ private final UserRepository userRepository; // 1. 패스워드는 알아서 체킹하니까 신경쓸 필요가 없다. // 2. 리턴이 잘되면 자동으로 UserDetails 타입을 세션으로 만든다. @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User userEntity = userRepository.findByUsername(username); if(userEntity == null) { return null; }else { return new PrincipalDetails(); } } }
Java
복사
아까 만든 PrincipalDetails.java 는 지금 틀만 잡아준거라 User 오브젝트를 추가해주자.
그리고 @Data도 추가.
private User user; public PrincipalDetails(User user) { this.user = user; }
Java
복사
그러면 여기가 오류나니까
@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User userEntity = userRepository.findByUsername(username); if(userEntity == null) { return null; }else { return new PrincipalDetails(userEntity); } }
Java
복사
userEntity를 넣어주면 된다!!!
new PrincipalDetails(userEntity)가 세션이 저장될때 세션에 저장된 User 오브젝트를 나중에도 활용할 수 있다.
package com.cos.photogramstart.config.auth; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import com.cos.photogramstart.domain.user.User; import lombok.Data; @Data public class PrincipalDetails implements UserDetails{ private static final long serialVersionUID = 1L; private User user; public PrincipalDetails(User user) { this.user = user; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { // TODO Auto-generated method stub return null; } @Override public String getPassword() { return user.getPassword(); } @Override public String getUsername() { return user.getUsername(); } @Override public boolean isAccountNonExpired() { //계정이 만료가 되었는 return true; //false가 맞는거다(로그인을 위해서 true로 변경) } @Override public boolean isAccountNonLocked() {//계정이 잠겼는가 return true; //false가 맞는거다(로그인을 위해서 true로 변경) } @Override public boolean isCredentialsNonExpired() { //비밀번호가 오랫동안 안바뀐거 아닌가 return true; //false가 맞는거다(로그인을 위해서 true로 변경) } @Override public boolean isEnabled() { //계정이 활성화 되어있는가 return true; //false가 맞는거다(로그인을 위해서 true로 변경) } }
Java
복사
@Override public Collection<? extends GrantedAuthority> getAuthorities() { // TODO Auto-generated method stub return null; }
Java
복사
잘보면 요부분이 권한관련 부분인데
//권한: 한개가 아닐 수 있음. (3개 이상의 권한) @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> collector = new ArrayList<>(); collector.add(new GrantedAuthority() { @Override public String getAuthority() { return user.getRole(); } }); return collector; }
Java
복사
Collection 타입때문에 이렇게 지저분하게 변경됐다 이걸 람다식으로 깔끔하게 처리하면
//권한: 한개가 아닐 수 있음. (3개 이상의 권한) @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> collector = new ArrayList<>(); collector.add(() -> { return user.getRole(); }); return collector; }
Java
복사
요렇게 심플하게 바꿀 수 있다.
add 안에 함수를 넣고 싶었던게 목적.
자바에서는 매개변수에 함수를 못넣는다. 자바는 함수가 일급객체가 아니기 때문에
여기에 인터페이스를 넣어줘야한다. 혹은 클래스 오브젝트를 넘긴다.
다시 로그인을 진행해보자.
로그인 성공! 404 코드가 떳다는건
/ 주소는 우리가 전에 403코드로 다른 주소로 이동하게 했었는데 403으로 안뜨고 404로 뜬건 로그인이 성공했다는 뜻이다.
/user 주소 쳐도 404코드가 나온다
확실하게 알고싶으면
다시 주소에 http://localhost:8080/logout 쳐서 로그아웃하고
주소에 http://localhost:8080/user 라 쳐도 메인로그인 화면으로 넘어온다
왜냐면 세션이 없어서 그렇다.

*참고