이 시리즈에 나오는 모든 내용은 인프런 인터넷 강의 - [ 스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security ] - 에서 기반된 것입니다. 그리고 여기서 인용되는 PPT 이미지 또한 모두 해당 강의에서 가져왔음을 알립니다.
스프링 시큐리티의 로그아웃 기능의 동작방식은 아래와 같다.
Spring Security
가 로그아웃에 필요한 작업 수행SecurityContext
또한 삭제위 과정뿐만 아니라 개발자가 원한다면 커스텀하게 로그아웃 작업을 추가할 수도 있다.
아래에 그 방법이 나온다.
복습차원에서 이전에 했던 로그인 작업도 같이 작성한다.
하지만 이후로는 다 생략할 것이다.
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests(request -> request.anyRequest().authenticated());
http
.formLogin()
.usernameParameter("userId")
.passwordParameter("passwd")
.successHandler((request, response, authentication) -> {
response.sendRedirect("/");
})
.failureHandler((request, response, exception) -> {
response.sendRedirect("/login");
// 참고로 스프링 시큐리티가 제공하는 로그인 페이지 주소는
// "/login"이다.
})
.permitAll();
// 여기서부터 로그아웃 API 내용~!
http.logout()
.logoutUrl("/logout") // 로그아웃 처리 URL (= form action url)
//.logoutSuccessUrl("/login") // 로그아웃 성공 후 targetUrl,
// logoutSuccessHandler 가 있다면 효과 없으므로 주석처리.
.addLogoutHandler((request, response, authentication) -> {
// 사실 굳이 내가 세션 무효화하지 않아도 됨.
// LogoutFilter가 내부적으로 해줌.
HttpSession session = request.getSession();
if (session != null) {
session.invalidate();
}
}) // 로그아웃 핸들러 추가
.logoutSuccessHandler((request, response, authentication) -> {
response.sendRedirect("/login");
}) // 로그아웃 성공 핸들러
.deleteCookies("remember-me"); // 로그아웃 후 삭제할 쿠키 지정
}
}
addLogoutHandler api 추가설명
참고로 스프링 시큐리티는 로그아웃을 기본으로 POST 방식을 사용하도록 한다.
GET 방식으로 바꿀 수 있다. 그 방법은 추후에 알아보는 걸로...
위의 과정들을 코드를 통해서 확인해보자.
아래 코드는 LogoutFilter
클래스의 doFilter 메소드의 내용이다.
보면 알겠지만, 인증 객체를 SecurityContext 에서 빼와서
this.handler.logout(request, response, auth)
this.logoutSuccessHandler.onLogoutSuccess(request, response, auth)
각각에게 인자값으로 보내는 것을 확인할 수 있다.
즉 위 2개의 메소드 내에서 어떤 처리를 한다는 의미다.
각 메소드의 내용을 하나하나 확인해보자.
위 그림은 this.handler.logout(request, response, auth)
의 내용이다.
메소드 내에서는 for loop 를 돌아서 갖고 있는 Handler 들의 작업을 수행한다.
logoutHandlers 리스트의 내용물을 자세히 보면 아래와 같은 것들이 있다.
http.logout().addLogoutHandler
api 로 추가한 커스텀 LogoutHandler 이다.http.logout().deleteCookies("remember-me");
api 에서 지정한 쿠키를 지움위의 핸들러 중에서도 SecurityContextLogoutHandler
가 중요하므로 해당 내용만 보자.
하는 일은 아래와 같다.
이 메소드는 http.logout().logoutSuccessHandler()
api 를 통해서 직접
SuccessHandler
를 작성했다면 해당 Handler
가 호출되고 끝난다.
하지만 만약에 그렇지 않다면? SimpleUrlLogoutSuccessHandler
가 기본으로
호출되고 내부적으로 redirect 시킬 targetUrl 을 결정한 후, redirect 시킨다.
만약 어떠한 사용자 지정도 없다면 targetUrl="/login?logout"
이 되고,
만약 사용자가 http.logout().logoutSuccessUrl("/login")
API 로 targetUrl 을 지정했다면 해당 위치로 redirect 시킨다.