MakerHyeon

[springBoot] 로그인 기능 구현 본문

SpringBoot

[springBoot] 로그인 기능 구현

유쾌한고등어 2023. 1. 5. 17:10

로그인 기능 구현

 

1. POST 로그인요청

- 원래 SELECT할때는 GET을 쓰지만,로그인을 할때는 POST를 쓴다.

- GET은 주소창에 데이터를 노출시켜서,로그인요청을 할때는 Data를 Body에 안고 가기 위해 POST사용

 <!--signin.jsp-->

 <!--로그인 인풋-->
<form class="login__input" action="/auth/signin" method="POST">
    <input type="text" name="username" placeholder="유저네임" required="required" />
    <input type="password" name="password" placeholder="비밀번호" required="required" />
    <button>로그인</button>
</form>

 

 

2. loginProcessingUrl에 '로그인 요청 url' 등록

// SecurityConfig.java

@EnableWebSecurity // 해당 파일로 시큐리티를 활성화
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder encode(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http); //기존 시큐리티가 가지고 있는 기능이 다 비활성화 됨
        http.csrf().disable();
        http.authorizeRequests()
            .antMatchers("/","/user/**","/image/**","/subscribe/**","/comment/**")
            .authenticated() //인증필요
            .anyRequest().permitAll()
            .and()
            .formLogin()
            .loginPage("/auth/signin")  //인증필요시 해당페이지로이동    // GET
            .loginProcessingUrl("/auth/signin") // POST ->스프링시큐리티가 로그인진행
            .defaultSuccessUrl("/");
    }
}

 

 

 


3. JPA query method 생성

// UserRepository.java

public interface UserRepository extends JpaRepository<User,Integer> {
    User findByUsername(String username);
}

 

 

4. PrincipalDetailsService 생성 후 UserDetailsService implements

- Password는 Security가 알아서 체킹하므로 신경 쓸 필요가 없다.

- Return이 잘되면,자동으로 UserDetails type session을 만든다.

// PrincipalDetailsService.java

@RequiredArgsConstructor
@Service
public class PrincipalDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User userEntity = userRepository.findByUsername(username);

        if(userEntity == null){
            return null;
        }else{
        //세션에 저장될때 세션에저장된 유저오브젝터 활용할 수 있게 한다.
            return new PrincipalDetails(userEntity);
        }
    }
}

 

 

5. PrincipalDetails.java 파일 생성(유저오브젝터 세션저장)

// PrincipalDetails.java
@Data
public class PrincipalDetails implements UserDetails {

    private static final long serialVersionUID = 1L;

    private User user;

    public PrincipalDetails(User user) {
        this.user = user;
    }

    // 권한 : 한개가 아닐 수 있음 (ex_3개 이상의 권한)
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() { //권한

        Collection<GrantedAuthority> collector = new ArrayList<>();
        collector.add(()->{return user.getRole();});

        return collector;
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }

    @Override
    public String getUsername() {
        return user.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

 

Feat. logout

-로그아웃시 security가 자동으로 세션을 끊어준다.

<button onclick="location.href='/logout'">로그아웃</button>

- Spring Data Query Creation 자세히 알아보기

 

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation

 

Spring Data JPA - Reference Documentation

Example 119. Using @Transactional at query methods @Transactional(readOnly = true) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

Comments