From 41b405f091a9496efdcc25aa3b85d32d5bf3a815 Mon Sep 17 00:00:00 2001 From: seonjuuu Date: Sun, 11 May 2025 02:22:47 +0900 Subject: [PATCH] =?UTF-8?q?[feat]=20feat:=20=EC=84=B8=EC=85=98=20=EB=B3=B4?= =?UTF-8?q?=EC=95=88=20=EA=B0=95=ED=99=94=20=EB=B0=8F=20=EB=A7=8C=EB=A3=8C?= =?UTF-8?q?=20=EC=8B=9C=20401=20=EC=9D=91=EB=8B=B5=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../User/config/SessionCheckFilterConfig.java | 19 +++++++++ .../exception/GlobalExceptionHandler.java | 1 + .../User/filter/SessionCheckFilter.java | 40 +++++++++++++++++++ .../pirocheck/User/service/UserService.java | 4 +- .../src/main/resources/application.yml | 10 ++++- 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 backend/pirocheck/src/main/java/backend/pirocheck/User/config/SessionCheckFilterConfig.java create mode 100644 backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java diff --git a/backend/pirocheck/src/main/java/backend/pirocheck/User/config/SessionCheckFilterConfig.java b/backend/pirocheck/src/main/java/backend/pirocheck/User/config/SessionCheckFilterConfig.java new file mode 100644 index 0000000..e5a2556 --- /dev/null +++ b/backend/pirocheck/src/main/java/backend/pirocheck/User/config/SessionCheckFilterConfig.java @@ -0,0 +1,19 @@ +package backend.pirocheck.User.config; + +import backend.pirocheck.User.filter.SessionCheckFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SessionCheckFilterConfig { + + @Bean + public FilterRegistrationBean sessionCheckFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new SessionCheckFilter()); + registrationBean.addUrlPatterns("/api/*"); + registrationBean.setOrder(1); + return registrationBean; + } +} diff --git a/backend/pirocheck/src/main/java/backend/pirocheck/User/exception/GlobalExceptionHandler.java b/backend/pirocheck/src/main/java/backend/pirocheck/User/exception/GlobalExceptionHandler.java index a135034..4fd3755 100644 --- a/backend/pirocheck/src/main/java/backend/pirocheck/User/exception/GlobalExceptionHandler.java +++ b/backend/pirocheck/src/main/java/backend/pirocheck/User/exception/GlobalExceptionHandler.java @@ -9,6 +9,7 @@ @RestControllerAdvice public class GlobalExceptionHandler { + // InvalidLoginException (로그인 실패) @ExceptionHandler(InvalidLoginException.class) public ResponseEntity> handleInvalidLoginException(InvalidLoginException e) { return ResponseEntity diff --git a/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java b/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java new file mode 100644 index 0000000..61a09c4 --- /dev/null +++ b/backend/pirocheck/src/main/java/backend/pirocheck/User/filter/SessionCheckFilter.java @@ -0,0 +1,40 @@ +package backend.pirocheck.User.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +public class SessionCheckFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) + throws ServletException, IOException { + + String path = request.getRequestURI(); + + // 로그인/로그아웃 요청은 세션 체크 제외 + if (path.startsWith("/api/login") || path.startsWith("/api/logout")) { + filterChain.doFilter(request, response); // 다음 필터나 컨트롤러로 넘기는 명령어 + return; // 세션 검사 안함 + } + + HttpSession session = request.getSession(false); // 세션이 없으면 새로 만들지 않고 null을 리턴 (true : 새로 생성) + + if (session == null || session.getAttribute("loginUser") == null) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 설정 + response.setContentType("application/json;charset=UTF-8"); + response.getWriter().write("{\"success\":false,\"message\":\"세션이 만료되었습니다.\",\"data\":null}"); + return; + } + + filterChain.doFilter(request, response); + + } +} diff --git a/backend/pirocheck/src/main/java/backend/pirocheck/User/service/UserService.java b/backend/pirocheck/src/main/java/backend/pirocheck/User/service/UserService.java index 04231cf..ff5fb5d 100644 --- a/backend/pirocheck/src/main/java/backend/pirocheck/User/service/UserService.java +++ b/backend/pirocheck/src/main/java/backend/pirocheck/User/service/UserService.java @@ -14,10 +14,10 @@ public class UserService { public User login(String name, String password) { User user = userRepository.findByName(name) - .orElseThrow(() -> new InvalidLoginException("해당 사용자가 존재하지 않습니다.")); + .orElseThrow(() -> new InvalidLoginException("해당 사용자가 존재하지 않습니다.")); //401 if (!user.getPassword().equals(password)) { - throw new InvalidLoginException("비밀번호가 일치하지 않습니다."); + throw new InvalidLoginException("비밀번호가 일치하지 않습니다."); //401 } return user; diff --git a/backend/pirocheck/src/main/resources/application.yml b/backend/pirocheck/src/main/resources/application.yml index 1416bb4..11c027f 100644 --- a/backend/pirocheck/src/main/resources/application.yml +++ b/backend/pirocheck/src/main/resources/application.yml @@ -11,4 +11,12 @@ spring: properties: hibernate: format_sql: true - open-in-view: false \ No newline at end of file + open-in-view: false +server: + servlet: + session: + cookie: + http-only: true # 세션 쿠키를 HttpOnly로 설정 (JS에서 접근 불가) + secure: false # HTTPS 전용 전송 (Https -> true로 바꿔야 함) + same-site: Lax # CSRF 방지 + timeout: 30m # 세션 타임아웃 30분 (30 minutes) \ No newline at end of file