포트폴리오/SPRINGBOOT 옛날

3-07 : 로그인과 로그아웃

서버관리자 페페 2022. 10. 9. 18:52

단 하나의 맥락

: 회원가입 form으로 가입 후, 로그인 로그아웃 authorize 구현

 


Semiflow Bundle

: 로그인 URL 등록

: 컨트롤러에 매핑

: 로그인 템플릿 작성

: 리포지터리에 사용자 조회 메서드 선언

: 권한 부여

: 로그인 처리를 위한 UserSecurityService 작성

: SecurityConfig에 UserSecurityService 등록

: 로그인 링크를 네비게이션 바에 등록

: 로그인으로 Authenticated되었으면 로그인 버튼을 로그아웃 버튼으로 변경

: SecurityConfig에 로그아웃 URL 처리

 


 

로그인 URL 등록

 

> SecurityConfig에서

 

XFrameOptionsHeaderWriter 하단

  • .and()
    • .formLogin()
    • .loginPage("/user/login")
    • .defaultSuccessUrl("/")
  • ;

작성

 

 

-

 

 

 로그인 URL 매핑 추가

 

> UserController에서

 

  • @GetMapping("/login")
  • M : public String login() {}
  • A1 : return "login_form"; 

작성

 

템플릿만 렌더링하고,

실제 로그인을 진행하는 PostMapping Method는 스프링 시큐리티가 대신 처리하므로, 구현하지 않아도 된다

 

 

-

 

로그인 템플릿 작성

 

> login_form.html 신규 작성

 

 

외부 플러그인

  • <html layout:decorate="~{layout}"></html> 내부 
  • <div layout:fragment="content"   class="container my-3"></div> 

 

폼 형식

  • <form th:action="@{user/login}"  method="post"></form> 내부 최상단
  • <div th:if="${param.error}"></div> 내부
  • <div class="alert alert-danger">사용자 ID 또는 비밀번호를 확인해주세요</div> 로 err msg 구현
  • <button type="submit"  class="btn btn-primary">로그인</button> 최하단에 구현

 

로그인 

  • <div class="mb-3"></div> 내부
  • <label for="username"  class="form-label">사용자 ID</label>
  • <input type="text"  name="username"  id="username"  class="form-control">

 

로그아웃

  • <div class="mb-3"></div> 내부
  • <label for="password"  class="form-label">비밀번호</label>
  • <input type="password"  name="password"  id="password"  class="form-control">

 

 

-

 

 

사용자 조회를 위해 리포지터리에 메서드 추가

 

> UserRepository에

 

  • public interface UserRepository extends JpaRepository<SiteUser, Long> { }
    • Optional<SiteUser> findByusername(String username); 추가

 

// import java.util.Optional

 

 

 

-

 

 

 

인증 후 사용자에게 부여할 권한을 USER, ADMIN 2가지로 관리

 

> UserRole.java 신규작성

 

  • @Getter
  • public enum UserRole {}
    • P1 : ADMIN("ROLE_ADMIN"),
    • P2 : USER("ROLE_USER");   
    •  
    • M : UserRole(String value) { }
      • this.value = value;
    • P3 : private String value;

 

 

-

 

 

UserDetailsService 인터페이스 구현하여 로그인 처리

 

> UserSecurityService 신규 작성

 

@Service 

@RequriedArgsConstructor

public class UserSercurityService implements UserDetailsService {}

  • P1 : private final UserRepository userRepository;

 

  • @Override
  • M : public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {}
    • A1 : Optional<SiteUser> _siteUser = this.userRepository.findByusername(username);
    • A2 : if (_siteUser.isEmpty()) { throw new UsernameNotFoundException("사용자를 찾을 수 없습니다"); }
    • A3 : SiteUser siteUser = _siteUser.get();
    • A4 : List<GrantedAuthority> authorities = new ArrayList<>();
    • A5 :
      • if ("admin".equals(username)) {
        • authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue())); 
      • } else {
        • authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue())); }
    • A6 : return new User(siteUser.getUsername(), siteUser.getPassword(), authorities);

 

// import org.springframework.security.core.GrantedAuthority;

// import org.springframework.security.core.authority.SimpleGrantedAuthority;

// import org.springframework.security.core.userdetails.User;

// 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;  

 

 

-

 

스프링 시큐리티에 UserSecurityService 등록

 

> SecurityConfig에서

 

  • P1 : private final UserSecurityService userSecurityService; 추가
  •  
  • @Bean
  • M : public AuthenticationManager authenticationManager
  • S : (AuthenticationConfiguration authenticationConfiguration)
  • HE : throws Exception {} 
  • A1 : return authenticationConfiguration.getAuthenticationManager();

 

// class에 @RequiredArgsConstructor 추가

// import com.mysite.sbb.user.UserSecurityService; 필요

// import org.springframework.security.authentication.AuthenticationManager;

// import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;

 

 

-

 

로그인 링크를 네비게이션 바에 추가

 

> navbar.html 에서

 

  • <li class="nav-item"></li> 사이
  • <a class="nav-link"  th:href="@{/user/login}">로그인</a>

 

 

-

 

인증 여부를 사용하여 로그인/로그아웃 버튼 조절

 

> navbar.html 에서

 

  • <li class="nav-item"></li> 사이
  • <a class="nav-link"  sec:authorize="isAnonymous()"  th:href="@{/user/login}">로그인</a>
  • <a class="nav-link"  sec:authorize="isAuthenticated()"  th:href="@{/user/logout}">로그아웃</a>

로 위상별 표시

 

 

-

 

로그아웃 구현하기

 

> SecurityConfig에서

 

  • .and()
    • .logout()
    • .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
    • .logoutSuccessUrl("/")
    • .invalidateHttpSession(true)
  • ;

추가

'포트폴리오 > SPRINGBOOT 옛날' 카테고리의 다른 글

3 - 09 : 글쓴이 표시  (0) 2022.10.10
3-08 : entity에 author 추가하기  (0) 2022.10.10
3-06 : 회원가입  (0) 2022.10.09
3-05 : spring security  (3) 2022.10.09
3-04 : 답변 갯수 표시  (0) 2022.10.09