Spring security에서의 로그인/로그아웃

김건우·2023년 1월 30일
0

Spring Security

목록 보기
3/4
post-thumbnail

SecurityConfig 로그인 / 로그아웃 설정

  • SecurityConfig🔽
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
        //form Login 기능 사용
        http.formLogin()
                .loginPage("/login").permitAll();
        //form Logout 기능 사용 로그아웃 성공시 -> "/"
        http.logout()
                .logoutSuccessUrl("/");


    }
   }

위와 같이 설정하고 login.html의 form에서 th:action="@{/login}" method="post"와 같이 설정한다면 post로 가는 /login 요청을 formLogin을 처리하는 시큐리티가 처리해준다.

🎉 장점과 효과

따로 url ="/login" post를 처리하는 핸들러를 만들 필요가 없음.
PasswordEncoder도 Bean으로 등록이 되어있다면 자동으로 사용이 된다. (하나만 있는 경우)알아서 username과 password를 가지고 로그인을 처리한다. 이 때, 데이터베이스에 저장된 정보를 참조하여 인증을 하여야 하기 때문에 데이터베이스를 조회할 수 있는 UserDetailsService를 구현해야 한다.

🔍 UserDetailService를 구현하기 전에 우선 NickName과 Email 둘 중 하나라도 입력하면 로그인 되게 구현할 것이다.

  • UserDetailService 구현

    @Service
    @RequiredArgsConstructor
    public class AccountService implements UserDetailsService {
    
       private final AccountRepository accountRepository;
    
       @Override
       public UserDetails loadUserByUsername(String emailOrNickname) throws UsernameNotFoundException {
           Account account = accountRepository.findByEmail(emailOrNickname);
           if(account == null){ // 이메일로 찾지 못한 경우 닉네임으로 찾는다.
               account = accountRepository.findByNickname(emailOrNickname);
           }
           if(account == null){ // 닉네임으로도 찾지 못한다면 에러를 던짐
               throw new UsernameNotFoundException(emailOrNickname);
           }
           // Principal 에 해당하는 객체를 리턴한다.
           return new UserAccount(account);
       }
    }

    loadUserByUsername()

  • 상세 정보를 조회하는 메서드이며, 사용자 계정정보와 권한을 갖는 UserDetails인터페이스를 반환해야 한다.

  • 매개변수는 로그인 시 입력한 아이디이다. 엔티티의 PK를 뜻하는 것이 아니고, 유저를 식별할 수 있는 어떠한 값을 의미한다. 스프링 시큐리티에서는 username라는 이름으로 사용한다.

  • 로그인 form에서 아이디에 해당하는 값의 name=”username”으로 요청해야 한다.

  • UserDetailsService에서 return하는 객체는 UserDetails타입이어야 한다

  • 따라서 UserDetails를 구현하는 User클래스를 상속받은 UserAccount를 리턴한다.

login.html

📣 위에서 말한 것과 같이 아이디를 입력하는 input태그의 name에는 username으로 들어가야한다. 그래야 Spring security가 인식한다!

<form class="needs-validation col-sm-6" action="#" th:action="@{/login}" method="post" novalidate>
                <div class="form-group">
                    <label for="username">이메일 또는 닉네임</label>
                    <input id="username" type="text" name="username" class="form-control"
                           placeholder="your@email.com" aria-describedby="emailHelp" required>
                    <small id="emailHelp" class="form-text text-muted">
                        가입할 때 사용한 이메일 또는 닉네임을 입력하세요.
                    </small>
                    <small class="invalid-feedback">이메일을 입력하세요.</small>
                </div>
                <div class="form-group">
                    <label for="password">패스워드</label>
                    <input id="password" type="password" name="password" class="form-control"
                           aria-describedby="passwordHelp" required>
                    <small id="passwordHelp" class="form-text text-muted">
                        패스워드가 기억나지 않는다면, <a href="#" th:href="@{/email-login}">패스워드 없이 로그인하기</a>
                    </small>
                    <small class="invalid-feedback">패스워드를 입력하세요.</small>
                </div>

                <div class="form-group form-check">
                    <input type="checkbox" class="form-check-input" id="rememberMe" name="remember-me" checked>
                    <label class="form-check-label" for="rememberMe" aria-describedby="rememberMeHelp">로그인 유지</label>
                </div>

                <div class="form-group">
                    <button class="btn btn-success btn-block" type="submit"
                            aria-describedby="submitHelp">로그인</button>
                    <small id="submitHelp" class="form-text text-muted">
                        스터디올래에 처음 오신거라면 <a href="#" th:href="@{/signup}">계정을 먼저 만드세요.</a>
                    </small>
                </div>
            </form>
profile
Live the moment for the moment.

0개의 댓글