✅ 스프링 시큐리티 로그아웃 기능 이란?
인증
된 사용자가 로그아웃 요청을 했을 때
(서버세션 무효화, 인증정보와 쿠키 삭제, SecurityContext
도 비워주는) 보안 기능이다
이 과정을 통해 사용자는 안전하게 로그아웃 되고, 이후에는 인증이 필요한 리소스에 접근 불가능
SecurityContext
: 현재 인증된 사용자의 정보
와 권한
을 담고 있는 컨테이너(저장소)
✅ 기본적인 코드 구조
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout()
.logoutUrl("/logout") // 로그아웃 처리 URL
.logoutSuccessUrl("/login") // 로그아웃 성공 후 이동할 URL
.invalidateHttpSession(true) // 세션 무효화
.deleteCookies("JSESSIONID", "remember-me") // 쿠키 삭제
.addLogoutHandler(logoutHandler()) // 추가 로그아웃 핸들러(선택)
.logoutSuccessHandler(logoutSuccessHandler()); // 커스텀 성공 핸들러(선택)
}
}
logoutUrl("/logout")
: 로그아웃 요청을 받을 URL 지정
logoutSuccessUrl("/login")
: 로그아웃 후 이동할 URL 지정
invalidateHttpSession(true)
: 세션 무효화
deleteCookies(...)
: 쿠키 삭제
addLogoutHandler(...)
: 커스텀 핸들러 추가(선택)
logoutSuccessHandler(...)
: 로그아웃 성공 시 실행할 핸들러(선택)
여기서 커스텀 로그아웃 핸들러는 따로 작성하면 된다
.addLogoutHandler((request, response, authentication) -> {
// 추가 로그아웃 작업
})
.logoutSuccessHandler((request, response, authentication) -> {
response.sendRedirect("/login");
})
✅ Oauth 로그아웃과 일반 로그아웃 함께 구현
.logout(logout -> logout
.logoutUrl("/logout") // 로그아웃을 수행할 엔드포인트 URL을 지정 (사용자가 /logout으로 접속하면 이 설정이 실행)
.logoutSuccessHandler((request, response, authentication) -> { // 로그아웃이 성공적으로 처리된 후 실행되는 직접 구현한 로직
// 현재 세션 종료 및 인증 해제
HttpSession session = request.getSession(false);
if (session != null) { // 현재 세션이 존재하면
session.invalidate(); // 세션을 강제로 무효화
}
SecurityContextHolder.clearContext(); // Spring Security의 SecurityContext (로그인 정보 저장소) 를 초기화
// 로그아웃 후 리다이렉트 주소에 사용하기 위해 서버의 주소를 동적으로 생성
String currentHost = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
// 인증이 null인 경우 → 로그인 상태 아님 → 그냥 로그인 페이지로 보냄
if (authentication == null) {
response.sendRedirect(currentHost + "/login"); // /login 페이지로 리다이렉트
return;
}
// OAuth 로그인인지 확인 (카카오/구글 같은 OAuth2 로그인 사용자일 경우 true)
boolean isOauthUser = authentication.getPrincipal() instanceof org.springframework.security.oauth2.core.user.DefaultOAuth2User;
if (isOauthUser) {
// 🔒 카카오 로그아웃 URL로 리다이렉트
String kakaoLogoutUrl = "https://kauth.kakao.com/oauth/logout" +
"?client_id=" + KakaoConfig.CLIENT_ID +
"&logout_redirect_uri=" + URLEncoder.encode(currentHost + "/login", "UTF-8");
response.sendRedirect(kakaoLogoutUrl);
} else {
response.sendRedirect(currentHost + "/login"); // 일반 로그인 사용자 → 일반 로그아웃 처리
}
})
.invalidateHttpSession(true) // true -> 로그아웃 시 세션을 자동으로 무효화 (위에서 수동으로 했지만 이중으로 함)
.deleteCookies("JSESSIONID") // 로그아웃할 때 클라이언트에 저장된 세션 쿠키(JSESSIONID) 도 삭제 (보안을 위해서)
.permitAll() // 누구나 접근 가능
);