게시판 - 7

JIWOO YUN·2024년 4월 23일
0

게시판만들기

목록 보기
7/21
post-custom-banner

로그인 과 로그아웃 구현하기

  • 스프링 시큐리티를 활용하여 진행.
  • formLogin 이 성공할 경우 루트URL로 향하게
    • 실패할 경우 loginForm에 머물게 진행

SecurityConfig의 코드 추가

.formLogin((formLogin) -> formLogin.loginPage("/user/login")
        .defaultSuccessUrl("/"))
;

login_form 추가

<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-3">
    <form th:action="@{/user/login}" method="post">
        <div th:if="${param.error}">
            <div class="alert alert-danger">
                사용자ID 또는 비밀번호를 확인해 주세요.
            </div>
        </div>
        <div class="mb-3">
            <label for="username" class="form-label">사용자ID</label>
            <input type="text" name="username" id="username" class="form-control">
        </div>
        <div class="mb-3">
            <label for="password" class="form-label">비밀번호</label>
            <input type="password" name="password" id="password" class="form-control">
        </div>
        <button type="submit" class="btn btn-primary">로그인</button>
    </form>
</div>
</html>

관리자와 사용자의 역할을 나누기 위한 UserRole 추가

public enum UserRole {
    ADMIN("ROLE_ADMIN"),
    USER("ROLE_USER");

    private String value;

    UserRole(String value) {
        this.value = value;
    }
}
  • 관리자 역할을 가진 id와 사용자 역할을 가지는 id를 나누기 위한 enum을 추가하여 관리할 수 있도록 했다.

UserSecurityService 생성

  • Spring Security에서 제공하는 UserDetailService 인터페이스를 구현을 진행
    • UserDetailService 인터페이스는 loadUserByUsername메서드를 구현을 강제하도록함.
      • 사용자 명으로 스프링 시큐리티의 사용자 객체를 조회하여 리턴하는 메서드
      • 만약 사용자명이 admin인경우 admin 역할을 부여해주고 이외의 경우 USER 역할을 부여해준다.
      • 마지막에 User 객체를 반환 -> 스프링 시큐리티에서 제공하는 객체
        • 이 객체에 들어있는값은 사용자명,비밀번호,권한 리스트가 포함되어있다.
        • 비밀번호의 경우 사용자로 부터 입력받은 비밀번호와 일치하는지 검사하는 기능이 내부에 탑재되어있음.
@RequiredArgsConstructor
@Service
public class UserSecurityService implements UserDetailsService {

    private final UserRepository userRepository;

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

        Optional<SiteUser> siteUser = userRepository.findByusername(username);

        if (siteUser.isEmpty()) {
            throw new UsernameNotFoundException("사용자를 찾을 수 없음.");
        }

        SiteUser user = siteUser.get();
        List<GrantedAuthority> authorities = new ArrayList<>();
        if ("admin".equals(username)) {
            authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
        } else {
            authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue()));
        }

        return new User(user.getUsername(), user.getPassword(), authorities);
    }
}

SecurityConfig에 AnthenticationManager 추가

@Bean
AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {

    return authenticationConfiguration.getAuthenticationManager();
}
  • 스프링 시큐리티의 인증을 처리하는 요소
  • ID와 Password를 Authentication 인증 객체에 저장하고 이 객체를 AuthenticationManager에게 전달
  • AuthenticationManager 는 사용자 인증 앞에서 작성한 UserSecurityService 와 PasswordEncoder를 내부적으로 사용하여 인증과 권한 부여 프로세스를 처리한다.

로그아웃 기능의 경우 SecurityConfig를 통해서 간단하게 구현이 가능

.logout((logout) -> logout
        .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
        .logoutSuccessUrl("/")
        .invalidateHttpSession(true))
  • 로그아웃 성공시 루트 URL로 이동
  • 마지막 invaludateHttpSession의 경우 로그아웃시 생성된 사용자 세션도 삭제되게 진행.
profile
열심히하자
post-custom-banner

0개의 댓글