Skip to content

Commit

Permalink
SCRUM-69 fix: 로그아웃 필터 위치 조정
Browse files Browse the repository at this point in the history
  • Loading branch information
softwareyong committed Aug 29, 2024
1 parent 59aac1d commit d0e63a7
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 58 deletions.
22 changes: 10 additions & 12 deletions src/main/java/com/kakaoteck/golagola/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kakaoteck.golagola.config;

import com.kakaoteck.golagola.security.filter.JwtAuthenticationFilter;
import com.kakaoteck.golagola.security.handler.signout.CustomSignOutProcessHandler;
import com.kakaoteck.golagola.security.jwt.JWTFilter;
import com.kakaoteck.golagola.security.jwt.JWTUtil;
import com.kakaoteck.golagola.security.handler.signin.CustomSuccessHandler;
Expand All @@ -12,6 +13,8 @@
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
Expand All @@ -34,9 +37,7 @@ public class SecurityConfig {
private final CustomOAuth2UserService customOAuth2UserService;
private final CustomSuccessHandler customSuccessHandler;
private final JWTUtil jwtUtil;
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authenticationProvider;
private final LogoutHandler logoutHandler;
private final CustomSignOutProcessHandler customSignOutProcessHandler;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
Expand All @@ -55,9 +56,6 @@ public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
}
}));




// CSRF 보호 비활성화
http.csrf(AbstractHttpConfigurer::disable);

Expand All @@ -76,14 +74,14 @@ public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
// 로그아웃 설정
http.logout(logout -> logout.logoutUrl("/api/v1/auth/logout")
//.addLogoutHandler(logoutHandler) // 지미꺼
.addLogoutHandler(logoutHandler) // 코이꺼

.deleteCookies("JSESSIONID", "Authorization")
.addLogoutHandler(customSignOutProcessHandler) // 코이꺼
.deleteCookies("JSESSIONID", "Authorization", "RefreshToken")
);

// JWT 필터 설정
// http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(new JWTFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class);
http.addFilterBefore(new JWTFilter(jwtUtil), LogoutFilter.class); // 로그아웃 필터전에 jwt필터실행
http.addFilterBefore(new JWTFilter(jwtUtil), UsernamePasswordAuthenticationFilter.class);
// http.addFilterAfter(new JWTFilter(jwtUtil), OAuth2LoginAuthenticationFilter.class);

// 경로별 인가 작업
http.authorizeHttpRequests(auth -> auth
Expand All @@ -97,7 +95,7 @@ public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
}

private static final String[] WHITE_LIST_URL = {
"/api/v1/auth/**",
// "/api/v1/auth/**",
"/v2/api-docs",
"/v3/api-docs",
"/v3/api-docs/**",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
package com.kakaoteck.golagola.domain.auth.Repository;

import com.kakaoteck.golagola.domain.auth.entity.UserEntity;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.util.Optional;

public interface UserRepository extends JpaRepository<UserEntity, Long> {
// UserEntity findByUsername(String username); // username을 전달하여 해당하는 엔티티 가져오기(JPA)

Optional<UserEntity> findByUsername(String username); // 차이가 뭔지 공부하기

@Modifying
@Query("UPDATE UserEntity u SET u.refreshToken = :refreshToken, u.loginStatus = :loginStatus WHERE u.username = :username")
void updateRefreshTokenAndLoginStatus(@Param("userName") String username,
@Param("refreshToken") String refreshToken,
@Param("loginStatus") boolean loginStatus);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@ public String getUsername() {
return userDTO.getUsername();
}

public Long getId() { // id 값을 반환하는 메서드 추가
return userDTO.getId();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
@Setter
public class UserDTO {

private Long id; // 엔티티의 id 추가
private String role;
private String name;
private String username;
private String email; // 엔티티의 email 추가
private String refreshToken; // 엔티티의 refreshToken 추가
private boolean loginStatus; // 엔티티의 loginStatus 추가
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public class UserEntity {
private String role;

// 추가
private String RefreshToken; // JWT 리프레시 토큰 발급
private boolean LoginStatus; // 로그인 상태처리
private String refreshToken; // JWT 리프레시 토큰 발급
private boolean loginStatus; // 로그인 상태처리



Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
//package com.kakaoteck.golagola.security.handler.signout;
//
//
//import jakarta.servlet.http.HttpServletRequest;
//import jakarta.servlet.http.HttpServletResponse;
//import jakarta.transaction.Transactional;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.web.authentication.logout.LogoutHandler;
//import org.springframework.stereotype.Component;
//
//@Component
//@RequiredArgsConstructor
//@Slf4j
//public class CustomSignOutProcessHandler implements LogoutHandler {
//// private final UserRepository userRepository;
////
//// @Override
//// @Transactional
//// public void logout(HttpServletRequest request, HttpServletResponse response,
//// Authentication authentication) {
//// if (authentication == null) {
//// return;
//// }
////
//// CustomUserDetails userPrincipal = (CustomUserDetails) authentication.getPrincipal();
////
//// userRepository.updateRefreshTokenAndLoginStatus(userPrincipal.getId(), null, false);
//// }
//
//
//}
//
//
//
//
//
//
//
package com.kakaoteck.golagola.security.handler.signout;


import com.kakaoteck.golagola.domain.auth.Repository.UserRepository;
import com.kakaoteck.golagola.domain.auth.dto.CustomOAuth2User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
@Slf4j
public class CustomSignOutProcessHandler implements LogoutHandler {
private final UserRepository userRepository;

@Override
@Transactional
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
if (authentication == null) {
return;
}

// 1. 테리코드
// CustomUserDetails userPrincipal = (CustomUserDetails) authentication.getPrincipal();
// userRepository.updateRefreshTokenAndLoginStatus(userPrincipal.getId(), null, false);

// 2. 용우코드
CustomOAuth2User userPrincipal = (CustomOAuth2User) authentication.getPrincipal(); // CustomOAuth2User 사용
System.out.println("로그아웃 정보 확인"+ userPrincipal + userPrincipal.getUsername());
userRepository.updateRefreshTokenAndLoginStatus(userPrincipal.getUsername(), null, false); // UserEntity에서 해당 유저를 찾아서 리프레시 토큰과 로그인 상태를 업데이트

}


}







19 changes: 16 additions & 3 deletions src/main/java/com/kakaoteck/golagola/security/jwt/JWTFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ public JWTFilter(JWTUtil jwtUtil) {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

// jwt 기간 만료시, 무한 재로그인 방지 로직
String requestUri = request.getRequestURI();
if (requestUri.matches("^\\/login(?:\\/.*)?$")) {

filterChain.doFilter(request, response);
return;
}
if (requestUri.matches("^\\/oauth2(?:\\/.*)?$")) {

filterChain.doFilter(request, response);
return;
}

// cookie들을 불러온 뒤 Authorization Key에 담긴 쿠키를 찾음
String authorization = null;
Cookie[] cookies = request.getCookies();
Expand All @@ -38,7 +51,6 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
}
}
}

// Authorization 헤더 검증
if (authorization == null) {
System.out.println("token null");
Expand All @@ -59,6 +71,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
// 토큰에서 username과 role 획득
String username = jwtUtil.getUsername(token);
String role = jwtUtil.getRole(token);
System.out.println("jwtfilter jwt확인: " + username + role);

// userDTO를 생성하여 값 set
UserDTO userDTO = new UserDTO();
Expand All @@ -68,13 +81,13 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
// UserDetails에 회원 정보 객체 담기
CustomOAuth2User customOAuth2User = new CustomOAuth2User(userDTO);

// 스프링 시큐리티 인증 토큰 생성
// 스프링 시큐리티 인증 토큰 생성, 스프링 시큐리티에서 세션을 생성해가지고 토큰을 등록하고 있음.
Authentication authToken = new UsernamePasswordAuthenticationToken(customOAuth2User, null, customOAuth2User.getAuthorities());

// 세션에 사용자 등록
SecurityContextHolder.getContext().setAuthentication(authToken);

filterChain.doFilter(request, response);
filterChain.doFilter(request, response); // jwtfilter작업을 다 했기 때문에 다음 필터에게 작업을 넘긴다는 doFilter작업을 진행해주시면 됩니다.
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// OAuth2UserRequest: 리소스 서버에서 제공되는 유저정보
@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {

private final UserRepository userRepository;

public CustomOAuth2UserService(UserRepository userRepository) {
Expand Down

0 comments on commit d0e63a7

Please sign in to comment.