Skip to content

Commit

Permalink
✨ [STMT-146] 로그아웃 기능 구현 (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
zxcv9203 authored Feb 24, 2024
2 parents f6bfe64 + f6ab4e6 commit fbf9694
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
import com.stumeet.server.common.auth.filter.JwtAuthenticationFilter;
import com.stumeet.server.common.auth.filter.OAuthAuthenticationFilter;
import com.stumeet.server.common.auth.handler.InvalidAuthenticationFailureHandler;
import com.stumeet.server.common.auth.handler.JwtLogoutHandler;
import com.stumeet.server.common.auth.handler.JwtLogoutSuccessHandler;
import com.stumeet.server.common.auth.handler.OAuthAuthenticationSuccessHandler;
import com.stumeet.server.common.auth.service.JwtAuthenticationService;
import com.stumeet.server.common.auth.service.OAuthAuthenticationProvider;
import com.stumeet.server.common.token.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
Expand All @@ -21,6 +24,7 @@
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration
@RequiredArgsConstructor
Expand All @@ -34,6 +38,8 @@ public class SecurityConfig {
private final OAuthAuthenticationSuccessHandler oAuthAuthenticationSuccessHandler;
private final AuthenticationEntryPoint authenticationEntryPoint;
private final AccessDeniedHandler accessDeniedHandler;
private final JwtLogoutHandler jwtLogoutHandler;
private final JwtLogoutSuccessHandler jwtLogoutSuccessHandler;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
Expand All @@ -52,6 +58,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.addFilterBefore(new OAuthAuthenticationFilter(invalidAuthenticationFailureHandler, authenticationManager, oAuthAuthenticationSuccessHandler), UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider, jwtAuthenticationService), UsernamePasswordAuthenticationFilter.class);

http.logout(logout -> {
logout.addLogoutHandler(jwtLogoutHandler);
logout.logoutSuccessHandler(jwtLogoutSuccessHandler);
logout.logoutRequestMatcher(new AntPathRequestMatcher("/api/v1/logout", HttpMethod.POST.name()));
});

http.authorizeHttpRequests(auth -> {
auth.requestMatchers("/api/v1/oauth").permitAll();
auth.requestMatchers("/api/v1/tokens").permitAll();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.stumeet.server.common.auth.handler;

import com.stumeet.server.common.auth.model.AuthenticationHeader;
import com.stumeet.server.common.token.service.RefreshTokenService;
import com.stumeet.server.common.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class JwtLogoutHandler implements LogoutHandler {

private final RefreshTokenService refreshTokenService;

@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
String token = request.getHeader(AuthenticationHeader.ACCESS_TOKEN.getName());

String accessToken = JwtUtil.resolveToken(token);
if (accessToken == null) {
throw new BadCredentialsException("유효하지 않은 토큰입니다. token : " + token);
}

refreshTokenService.deleteByAccessToken(accessToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.stumeet.server.common.auth.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.stumeet.server.common.model.ApiResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@RequiredArgsConstructor
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {

private final ObjectMapper objectMapper;

@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
ApiResponse<Void> responseBody = ApiResponse.success(HttpStatus.OK.value(), "로그아웃에 성공했습니다.");

response.setStatus(HttpServletResponse.SC_OK);
response.setCharacterEncoding("UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(responseBody));
}
}

0 comments on commit fbf9694

Please sign in to comment.