From a09cf30c2b6077352b617d462a5fee0aaa5fb368 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Wed, 26 Mar 2025 21:46:11 +0900
Subject: [PATCH 1/9] =?UTF-8?q?feat:=20DB=20=ED=95=84=EB=93=9C=20=EC=83=81?=
 =?UTF-8?q?=EC=84=B8=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20=EC=8B=9C=EA=B0=84?=
 =?UTF-8?q?=20=EC=96=91=EC=8B=9D=20=EC=84=A4=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/aolda/itda/dto/forwarding/ForwardingDTO.java   | 5 +++++
 src/main/java/com/aolda/itda/dto/log/LogDTO.java            | 5 +++++
 src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java    | 3 +++
 src/main/java/com/aolda/itda/entity/BaseTimeEntity.java     | 4 ++--
 .../java/com/aolda/itda/entity/certificate/Certificate.java | 4 ++++
 .../java/com/aolda/itda/entity/forwarding/Forwarding.java   | 6 ++++++
 src/main/java/com/aolda/itda/entity/log/Log.java            | 4 ++++
 src/main/java/com/aolda/itda/entity/routing/Routing.java    | 5 +++++
 8 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java b/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java
index 3302d0a..be003b6 100644
--- a/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java
+++ b/src/main/java/com/aolda/itda/dto/forwarding/ForwardingDTO.java
@@ -1,5 +1,6 @@
 package com.aolda.itda.dto.forwarding;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.Pattern;
@@ -40,6 +41,10 @@ public class ForwardingDTO {
 
     @NotBlank(message = "name 값이 존재하지 않습니다")
     private String name;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime createdAt;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime updatedAt;
 }
diff --git a/src/main/java/com/aolda/itda/dto/log/LogDTO.java b/src/main/java/com/aolda/itda/dto/log/LogDTO.java
index 5895455..9946028 100644
--- a/src/main/java/com/aolda/itda/dto/log/LogDTO.java
+++ b/src/main/java/com/aolda/itda/dto/log/LogDTO.java
@@ -3,6 +3,7 @@ package com.aolda.itda.dto.log;
 import com.aolda.itda.dto.auth.IdAndNameDTO;
 import com.aolda.itda.entity.log.Action;
 import com.aolda.itda.entity.log.ObjectType;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import com.querydsl.core.annotations.QueryProjection;
 import lombok.AllArgsConstructor;
@@ -22,7 +23,11 @@ public class LogDTO {
     private Action action;
     private ObjectType type;
     private Long objectId;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private String description;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime createdAt;
 
     @QueryProjection
diff --git a/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java b/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java
index 6bc48d8..985056e 100644
--- a/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java
+++ b/src/main/java/com/aolda/itda/dto/routing/RoutingDTO.java
@@ -1,5 +1,6 @@
 package com.aolda.itda.dto.routing;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonInclude;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotNull;
@@ -28,8 +29,10 @@ public class RoutingDTO {
     @NotNull
     private Long certificateId;
 
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime createdAt;
 
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime updatedAt;
 
     @NotNull
diff --git a/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java b/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java
index 6cfa1fd..b62af84 100644
--- a/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java
+++ b/src/main/java/com/aolda/itda/entity/BaseTimeEntity.java
@@ -17,12 +17,12 @@ import java.time.LocalDateTime;
 public abstract class BaseTimeEntity {
 
     @CreatedDate
-    @Column(updatable = false)
+    @Column(updatable = false, columnDefinition = "DATETIME")
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime createdAt;
 
     @LastModifiedDate
-    @Column(name = "updated_at")
+    @Column(name = "updated_at", columnDefinition = "DATETIME")
     @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
     private LocalDateTime updatedAt;
 
diff --git a/src/main/java/com/aolda/itda/entity/certificate/Certificate.java b/src/main/java/com/aolda/itda/entity/certificate/Certificate.java
index a23cf85..85b1f29 100644
--- a/src/main/java/com/aolda/itda/entity/certificate/Certificate.java
+++ b/src/main/java/com/aolda/itda/entity/certificate/Certificate.java
@@ -27,10 +27,13 @@ public class Certificate extends BaseTimeEntity {
     @JoinColumn(nullable = false, name = "user_id")
     private User user;
 
+    @Column(length = 64)
     private String projectId;
 
+    @Column(length = 64)
     private String domain;
 
+    @Column(length = 64)
     private String email;
 
     private LocalDateTime expiredAt;
@@ -40,6 +43,7 @@ public class Certificate extends BaseTimeEntity {
 
     private Boolean isDeleted;
 
+    @Column(length = 256)
     private String description;
 
     public String formatDomain() {
diff --git a/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java b/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java
index 0e5e505..0ba96d6 100644
--- a/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java
+++ b/src/main/java/com/aolda/itda/entity/forwarding/Forwarding.java
@@ -20,18 +20,24 @@ public class Forwarding extends BaseTimeEntity {
     @Column(nullable = false)
     private Long forwardingId;
 
+    @Column(length = 64)
     private String projectId;
 
+    @Column(length = 32)
     private String serverIp;
 
+    @Column(length = 8)
     private String serverPort;
 
+    @Column(length = 32)
     private String instanceIp;
 
+    @Column(length = 8)
     private String instancePort;
 
     private Boolean isDeleted;
 
+    @Column(length = 256)
     private String name;
 
     public Forwarding(Forwarding forwarding) {
diff --git a/src/main/java/com/aolda/itda/entity/log/Log.java b/src/main/java/com/aolda/itda/entity/log/Log.java
index 9832ab2..6bf6074 100644
--- a/src/main/java/com/aolda/itda/entity/log/Log.java
+++ b/src/main/java/com/aolda/itda/entity/log/Log.java
@@ -27,16 +27,20 @@ public class Log extends BaseTimeEntity {
     @JoinColumn(name = "user_id", nullable = false)
     private User user;
 
+    @Column(length = 64)
     private String projectId;
 
     @Enumerated(EnumType.STRING)
     private ObjectType objectType;
 
+    @Column(length = 64)
     private Long objectId;
 
     @Enumerated(EnumType.STRING)
     private Action action;
 
+    @Lob
+    @Column(length = 1024)
     private String description;
 
     public LogDTO toLogDTO() {
diff --git a/src/main/java/com/aolda/itda/entity/routing/Routing.java b/src/main/java/com/aolda/itda/entity/routing/Routing.java
index de13d82..94ecb55 100644
--- a/src/main/java/com/aolda/itda/entity/routing/Routing.java
+++ b/src/main/java/com/aolda/itda/entity/routing/Routing.java
@@ -28,18 +28,23 @@ public class Routing extends BaseTimeEntity {
     @JoinColumn(name = "certificate_id")
     private Certificate certificate;
 
+    @Column(length = 64)
     private String projectId;
 
+    @Column(length = 64)
     private String domain;
 
+    @Column(length = 32)
     private String instanceIp;
 
+    @Column(length = 8)
     private String instancePort;
 
     private Boolean isDeleted;
 
     private Boolean caching;
 
+    @Column(length = 256)
     private String name;
 
     public RoutingDTO toRoutingDTO() {
-- 
GitLab


From 62f400dffe4db2c570926c9a831617ed14a560e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Wed, 26 Mar 2025 22:39:01 +0900
Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?=
 =?UTF-8?q?=EC=96=B4=EB=93=9C=EB=AF=BC=20=ED=94=84=EB=A1=9C=EC=A0=9D?=
 =?UTF-8?q?=ED=8A=B8=20=EC=A0=91=EA=B7=BC=20=EA=B6=8C=ED=95=9C=20=EB=B6=80?=
 =?UTF-8?q?=EC=97=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../aolda/itda/config/AuthInterceptor.java    | 15 ++++++++---
 .../com/aolda/itda/config/LoggingFilter.java  |  3 ---
 .../com/aolda/itda/service/AuthService.java   | 25 +++++++++++++++++++
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
index 3a95f8a..b0767e3 100644
--- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java
+++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
@@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 import org.springframework.web.servlet.HandlerInterceptor;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -56,9 +57,17 @@ public class AuthInterceptor implements HandlerInterceptor {
         }
 
         /* 프로젝트 리스트 조회 */
-        List<String> projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token))
-                        .stream().map(IdAndNameDTO::getId)
-                        .toList();
+        List<String> projects;
+        if (authService.isAdmin(Map.of("id", userId, "token", token))) {
+            projects = authService.getAllProjects(token);
+        }
+
+        else {
+            projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token))
+                    .stream().map(IdAndNameDTO::getId)
+                    .toList();
+        }
+
         request.setAttribute("projects", projects);
         request.setAttribute("user", Map.of("id", userId, "token", token));
         return true;
diff --git a/src/main/java/com/aolda/itda/config/LoggingFilter.java b/src/main/java/com/aolda/itda/config/LoggingFilter.java
index 0dd73b1..49264ec 100644
--- a/src/main/java/com/aolda/itda/config/LoggingFilter.java
+++ b/src/main/java/com/aolda/itda/config/LoggingFilter.java
@@ -23,16 +23,13 @@ public class LoggingFilter extends OncePerRequestFilter {
 
         // Request Body를 읽을 수 있도록 래핑
         ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request);
-        System.out.println("필터 적용");
         filterChain.doFilter(cachingRequest, response);
 
         // 로그 기록
         logRequest(cachingRequest);
-        System.out.println("왜 안돼ㅐ");
     }
 
     private void logRequest(ContentCachingRequestWrapper request) {
-        System.out.println("되는거 맞아?");
         String ip = request.getRemoteAddr();
         String method = request.getMethod();
         String uri = request.getRequestURI();
diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java
index 6a25ebc..8bc6836 100644
--- a/src/main/java/com/aolda/itda/service/AuthService.java
+++ b/src/main/java/com/aolda/itda/service/AuthService.java
@@ -297,6 +297,31 @@ public class AuthService {
 
     }
 
+    public List<String> getAllProjects(String token) throws JsonProcessingException {
+        String url = keystone + "/projects";
+        HttpHeaders headers = new HttpHeaders();
+        headers.set("X-Auth-Token", token);
+        HttpEntity<String> requestEntity = new HttpEntity<>(headers);
+        ResponseEntity<String> res;
+        try {
+            res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
+        } catch (HttpClientErrorException.NotFound e) {
+            throw new CustomException(ErrorCode.INVALID_TOKEN);
+        }
+
+        JsonNode node = objectMapper.readTree(res.getBody());
+        ArrayNode arrayNode = (ArrayNode) node.get("projects");
+
+        List<String> lists = new ArrayList<>();
+
+        for (JsonNode assignment : arrayNode) {
+            lists.add(assignment.path("id").asText());
+        }
+
+        return lists;
+
+    }
+
     public void validateProjectAuth(List<String> projects, String projectId) {
         if (projects != null && !projects.contains(projectId)) {
             throw new CustomException(ErrorCode.UNAUTHORIZED_USER);
-- 
GitLab


From 1b407531c1208ef0f09867426b7cc75eafd20486 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Wed, 26 Mar 2025 23:39:18 +0900
Subject: [PATCH 3/9] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20=ED=8E=98?=
 =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=B0=8F=20=EC=A0=91=EA=B7=BC=20=EA=B0=80?=
 =?UTF-8?q?=EB=8A=A5=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../aolda/itda/config/AuthInterceptor.java    |  3 +-
 .../itda/controller/main/MainController.java  | 33 ++++++++++
 .../com/aolda/itda/dto/main/MainInfoDTO.java  | 20 ++++++
 .../com/aolda/itda/service/AuthService.java   |  8 ++-
 .../aolda/itda/service/main/MainService.java  | 61 +++++++++++++++++++
 5 files changed, 121 insertions(+), 4 deletions(-)
 create mode 100644 src/main/java/com/aolda/itda/controller/main/MainController.java
 create mode 100644 src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java
 create mode 100644 src/main/java/com/aolda/itda/service/main/MainService.java

diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
index b0767e3..7c9f87f 100644
--- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java
+++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
@@ -59,7 +59,8 @@ public class AuthInterceptor implements HandlerInterceptor {
         /* 프로젝트 리스트 조회 */
         List<String> projects;
         if (authService.isAdmin(Map.of("id", userId, "token", token))) {
-            projects = authService.getAllProjects(token);
+            projects = authService.getAllProjects(token).stream().map(IdAndNameDTO::getId)
+                    .toList();
         }
 
         else {
diff --git a/src/main/java/com/aolda/itda/controller/main/MainController.java b/src/main/java/com/aolda/itda/controller/main/MainController.java
new file mode 100644
index 0000000..7b22923
--- /dev/null
+++ b/src/main/java/com/aolda/itda/controller/main/MainController.java
@@ -0,0 +1,33 @@
+package com.aolda.itda.controller.main;
+
+import com.aolda.itda.service.main.MainService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+@RequiredArgsConstructor
+public class MainController {
+
+    private final MainService mainService;
+
+    @GetMapping("/projects")
+    public ResponseEntity<Object> projects(HttpServletRequest request) throws JsonProcessingException {
+        return ResponseEntity.ok(mainService.getAllProjects((Map<String, String>) request.getSession().getAttribute("user")));
+    }
+
+    @GetMapping("/main")
+    public ResponseEntity<Object> mainInfo(@RequestParam String projectId, HttpServletRequest request) {
+        return ResponseEntity.ok(mainService.getMainInfo(projectId, (List<String>) request.getAttribute("projects")));
+    }
+
+}
diff --git a/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java
new file mode 100644
index 0000000..6de5fdf
--- /dev/null
+++ b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java
@@ -0,0 +1,20 @@
+package com.aolda.itda.dto.main;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class MainInfoDTO {
+
+    private Long routing;
+    private Long forwarding;
+    private Long certificate;
+
+}
diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java
index 8bc6836..a222e28 100644
--- a/src/main/java/com/aolda/itda/service/AuthService.java
+++ b/src/main/java/com/aolda/itda/service/AuthService.java
@@ -297,7 +297,7 @@ public class AuthService {
 
     }
 
-    public List<String> getAllProjects(String token) throws JsonProcessingException {
+    public List<IdAndNameDTO> getAllProjects(String token) throws JsonProcessingException {
         String url = keystone + "/projects";
         HttpHeaders headers = new HttpHeaders();
         headers.set("X-Auth-Token", token);
@@ -312,10 +312,12 @@ public class AuthService {
         JsonNode node = objectMapper.readTree(res.getBody());
         ArrayNode arrayNode = (ArrayNode) node.get("projects");
 
-        List<String> lists = new ArrayList<>();
+        List<IdAndNameDTO> lists = new ArrayList<>();
 
         for (JsonNode assignment : arrayNode) {
-            lists.add(assignment.path("id").asText());
+            String projectId = assignment.path("id").asText();
+            String projectName = assignment.path("name").asText();
+            lists.add(new IdAndNameDTO(projectId, projectName));
         }
 
         return lists;
diff --git a/src/main/java/com/aolda/itda/service/main/MainService.java b/src/main/java/com/aolda/itda/service/main/MainService.java
new file mode 100644
index 0000000..2c36ac8
--- /dev/null
+++ b/src/main/java/com/aolda/itda/service/main/MainService.java
@@ -0,0 +1,61 @@
+package com.aolda.itda.service.main;
+
+import com.aolda.itda.dto.PageResp;
+import com.aolda.itda.dto.auth.IdAndNameDTO;
+import com.aolda.itda.dto.main.MainInfoDTO;
+import com.aolda.itda.repository.certificate.CertificateRepository;
+import com.aolda.itda.repository.forwarding.ForwardingRepository;
+import com.aolda.itda.repository.routing.RoutingRepository;
+import com.aolda.itda.service.AuthService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Transactional
+@RequiredArgsConstructor
+public class MainService {
+
+    private final AuthService authService;
+    private final RoutingRepository routingRepository;
+    private final ForwardingRepository forwardingRepository;
+    private final CertificateRepository certificateRepository;
+
+    /* 메인 페이지에 필요한 정보 반환 */
+    public MainInfoDTO getMainInfo(String projectId, List<String> projects) {
+
+        /* 프로젝트 권한 검증 */
+        authService.validateProjectAuth(projects, projectId);
+
+        /* 카운팅 */
+        Long routing = (long) routingRepository.findByProjectIdAndIsDeleted(projectId, false).size();
+        Long forwarding = (long) forwardingRepository.findByProjectIdAndIsDeleted(projectId, false).size();
+        Long certificate = 0L;
+
+        return MainInfoDTO.builder()
+                .routing(routing)
+                .forwarding(forwarding)
+                .certificate(certificate)
+                .build();
+    }
+
+    /* 접근 가능한 프로젝트 조회 */
+    public PageResp<IdAndNameDTO> getAllProjects(Map<String, String> user) throws JsonProcessingException {
+
+        List<IdAndNameDTO> projects;
+        if (authService.isAdmin(user)) {
+            projects = authService.getAllProjects(user.get("token"));
+        }
+
+        else {
+            projects = authService.getProjectsWithUser(user);
+        }
+
+        return PageResp.<IdAndNameDTO>builder()
+                .contents(projects).build();
+    }
+}
-- 
GitLab


From 017ea5c5ad239d906bdb7f85f9290a01dd99e8d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 11:08:48 +0900
Subject: [PATCH 4/9] =?UTF-8?q?fix:=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8?=
 =?UTF-8?q?=20=EC=97=AD=ED=95=A0=EA=B3=BC=20=EA=B6=8C=ED=95=9C=EC=9D=B4=20?=
 =?UTF-8?q?=EC=9D=BC=EC=B9=98=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8D=98=20?=
 =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/aolda/itda/config/AuthInterceptor.java |  6 +++---
 .../java/com/aolda/itda/service/AuthService.java    | 13 +++++--------
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
index 7c9f87f..fd78fb6 100644
--- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java
+++ b/src/main/java/com/aolda/itda/config/AuthInterceptor.java
@@ -43,10 +43,10 @@ public class AuthInterceptor implements HandlerInterceptor {
         if (projectId != null) {
 
             try {
-                String role = authService.getBestRoleWithinProject(token, projectId).get("role");
-                if (!role.equals("admin")) {
-                    log.error("Unauthorized Token for URI {}: {}", request.getRequestURI(), request.getRemoteAddr());
+                authService.getBestRoleWithinProject(token, projectId).get("role");
+                if (!request.getMethod().equals("GET") && !authService.getBestRoleWithinProject(token, projectId).get("role").equals("admin")) {
                     throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI());
+
                 }
             } catch (Exception e) {
                 throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI());
diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java
index a222e28..4c1740e 100644
--- a/src/main/java/com/aolda/itda/service/AuthService.java
+++ b/src/main/java/com/aolda/itda/service/AuthService.java
@@ -96,7 +96,6 @@ public class AuthService {
         try {
             res = restTemplate.postForEntity(url, requestEntity, Map.class);
         } catch (Exception e) {
-            e.printStackTrace();
             throw new CustomException(ErrorCode.INVALID_USER_INFO);
         }
         Map<String, Object> resToken = (Map<String, Object>) res.getBody().get("token");
@@ -140,7 +139,7 @@ public class AuthService {
         try {
             requestEntity = new HttpEntity<>(requestBody, headers);
             res = restTemplate.postForEntity(url, requestEntity, Map.class);
-        } catch (RuntimeException e) {
+        } catch (Exception e) {
             return null;
         }
 
@@ -185,8 +184,7 @@ public class AuthService {
         } catch (HttpClientErrorException.Forbidden e) {
             return unscopedToken;
         }
-        catch (RuntimeException e) {
-            e.printStackTrace();
+        catch (Exception e) {
             throw new CustomException(ErrorCode.INVALID_TOKEN);
         }
 
@@ -290,7 +288,7 @@ public class AuthService {
         ResponseEntity<String> res;
         try {
             res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
-        } catch (HttpClientErrorException.NotFound e) {
+        } catch (Exception e) {
             throw new CustomException(ErrorCode.INVALID_TOKEN);
         }
         return objectMapper.readTree(res.getBody()).path("token").path("user").path("id").asText();
@@ -305,7 +303,7 @@ public class AuthService {
         ResponseEntity<String> res;
         try {
             res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
-        } catch (HttpClientErrorException.NotFound e) {
+        } catch (Exception e) {
             throw new CustomException(ErrorCode.INVALID_TOKEN);
         }
 
@@ -338,8 +336,7 @@ public class AuthService {
         ResponseEntity<String> res;
         try {
             res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
-        } catch (RuntimeException e) {
-            e.printStackTrace();
+        } catch (Exception e) {
             return false;
         }
         JsonNode node = objectMapper.readTree(res.getBody()).path("role_assignments");
-- 
GitLab


From 1b0c96231a33afa111a7016e5289cfbea0930104 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 11:09:28 +0900
Subject: [PATCH 5/9] =?UTF-8?q?fix:=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20?=
 =?UTF-8?q?=EC=9E=91=EC=97=85=20=EB=A1=9C=EA=B7=B8=EC=97=90=20=EA=B0=9C?=
 =?UTF-8?q?=ED=96=89=EC=9D=B4=20=ED=95=9C=20=EB=B2=88=20=EB=8D=94=20?=
 =?UTF-8?q?=EB=93=A4=EC=96=B4=EA=B0=80=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java b/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java
index a3a67d2..97f7de4 100644
--- a/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java
+++ b/src/main/java/com/aolda/itda/aspect/RoutingLogAspect.java
@@ -61,7 +61,7 @@ public class RoutingLogAspect {
                 + "ip: " + routing.getInstanceIp() + "\n"
                 + "port: " + routing.getInstancePort() + "\n"
                 +  (routing.getCertificate() != null ? ("certificateId: " + routing.getCertificate().getCertificateId() + "\n") : "")
-                + "caching: " + routing.getCaching() + "\n";
+                + "caching: " + routing.getCaching();
 
         /* 로그 엔티티 저장 */
         logRepository.save(Log.builder()
@@ -97,7 +97,7 @@ public class RoutingLogAspect {
                 + "ip: " + routing.getInstanceIp() + "\n"
                 + "port: " + routing.getInstancePort() + "\n"
                 +  (routing.getCertificate() != null ? ("certificateId: " + routing.getCertificate().getCertificateId() + "\n") : "")
-                + "caching: " + routing.getCaching() + "\n";
+                + "caching: " + routing.getCaching();
 
         /* 로그 엔티티 저장 */
         logRepository.save(Log.builder()
-- 
GitLab


From aa911ace917181294680c8cf68ce89ef7b26fb3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 11:56:18 +0900
Subject: [PATCH 6/9] =?UTF-8?q?fix:=20enum=20type=20=EC=86=8C=EB=AC=B8?=
 =?UTF-8?q?=EC=9E=90=20=EC=A7=81=EB=A0=AC=ED=99=94=EB=A1=9C=20=EB=B3=80?=
 =?UTF-8?q?=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/aolda/itda/config/LoggingFilter.java  |  96 +++++-----
 .../itda/controller/main/MainController.java  |  66 +++----
 .../com/aolda/itda/dto/main/MainInfoDTO.java  |  40 ++--
 .../itda/entity/certificate/Challenge.java    |  12 +-
 .../com/aolda/itda/entity/log/Action.java     |  12 +-
 .../com/aolda/itda/entity/log/ObjectType.java |  12 +-
 .../aolda/itda/service/main/MainService.java  | 122 ++++++------
 src/main/resources/logback-spring.xml         | 178 +++++++++---------
 8 files changed, 284 insertions(+), 254 deletions(-)

diff --git a/src/main/java/com/aolda/itda/config/LoggingFilter.java b/src/main/java/com/aolda/itda/config/LoggingFilter.java
index 49264ec..f2330bf 100644
--- a/src/main/java/com/aolda/itda/config/LoggingFilter.java
+++ b/src/main/java/com/aolda/itda/config/LoggingFilter.java
@@ -1,48 +1,48 @@
-package com.aolda.itda.config;
-
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-import org.springframework.web.util.ContentCachingRequestWrapper;
-
-import java.io.IOException;
-
-@Component
-public class LoggingFilter extends OncePerRequestFilter {
-
-    private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-            throws ServletException, IOException {
-
-        // Request Body를 읽을 수 있도록 래핑
-        ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request);
-        filterChain.doFilter(cachingRequest, response);
-
-        // 로그 기록
-        logRequest(cachingRequest);
-    }
-
-    private void logRequest(ContentCachingRequestWrapper request) {
-        String ip = request.getRemoteAddr();
-        String method = request.getMethod();
-        String uri = request.getRequestURI();
-        String queryString = request.getQueryString();
-        String body = getRequestBody(request);
-
-        logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, Request Body: {}",
-                ip, method, uri, (queryString != null ? queryString : "None"),
-                (!body.isEmpty() ? body : "None"));
-    }
-
-    private String getRequestBody(ContentCachingRequestWrapper request) {
-        byte[] buf = request.getContentAsByteArray();
-        return (buf.length > 0) ? new String(buf) : "";
-    }
-}
+package com.aolda.itda.config;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.util.ContentCachingRequestWrapper;
+
+import java.io.IOException;
+
+@Component
+public class LoggingFilter extends OncePerRequestFilter {
+
+    private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+
+        // Request Body를 읽을 수 있도록 래핑
+        ContentCachingRequestWrapper cachingRequest = new ContentCachingRequestWrapper(request);
+        filterChain.doFilter(cachingRequest, response);
+
+        // 로그 기록
+        logRequest(cachingRequest);
+    }
+
+    private void logRequest(ContentCachingRequestWrapper request) {
+        String ip = request.getRemoteAddr();
+        String method = request.getMethod();
+        String uri = request.getRequestURI();
+        String queryString = request.getQueryString();
+        String body = getRequestBody(request);
+
+        logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, Request Body: {}",
+                ip, method, uri, (queryString != null ? queryString : "None"),
+                (!body.isEmpty() ? body : "None"));
+    }
+
+    private String getRequestBody(ContentCachingRequestWrapper request) {
+        byte[] buf = request.getContentAsByteArray();
+        return (buf.length > 0) ? new String(buf) : "";
+    }
+}
diff --git a/src/main/java/com/aolda/itda/controller/main/MainController.java b/src/main/java/com/aolda/itda/controller/main/MainController.java
index 7b22923..371cce5 100644
--- a/src/main/java/com/aolda/itda/controller/main/MainController.java
+++ b/src/main/java/com/aolda/itda/controller/main/MainController.java
@@ -1,33 +1,33 @@
-package com.aolda.itda.controller.main;
-
-import com.aolda.itda.service.main.MainService;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import jakarta.servlet.http.HttpServletRequest;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.List;
-import java.util.Map;
-
-@RestController
-@RequestMapping("/api")
-@RequiredArgsConstructor
-public class MainController {
-
-    private final MainService mainService;
-
-    @GetMapping("/projects")
-    public ResponseEntity<Object> projects(HttpServletRequest request) throws JsonProcessingException {
-        return ResponseEntity.ok(mainService.getAllProjects((Map<String, String>) request.getSession().getAttribute("user")));
-    }
-
-    @GetMapping("/main")
-    public ResponseEntity<Object> mainInfo(@RequestParam String projectId, HttpServletRequest request) {
-        return ResponseEntity.ok(mainService.getMainInfo(projectId, (List<String>) request.getAttribute("projects")));
-    }
-
-}
+package com.aolda.itda.controller.main;
+
+import com.aolda.itda.service.main.MainService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api")
+@RequiredArgsConstructor
+public class MainController {
+
+    private final MainService mainService;
+
+    @GetMapping("/projects")
+    public ResponseEntity<Object> projects(HttpServletRequest request) throws JsonProcessingException {
+        return ResponseEntity.ok(mainService.getAllProjects((Map<String, String>) request.getSession().getAttribute("user")));
+    }
+
+    @GetMapping("/main")
+    public ResponseEntity<Object> mainInfo(@RequestParam String projectId, HttpServletRequest request) {
+        return ResponseEntity.ok(mainService.getMainInfo(projectId, (List<String>) request.getAttribute("projects")));
+    }
+
+}
diff --git a/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java
index 6de5fdf..cbcdcd5 100644
--- a/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java
+++ b/src/main/java/com/aolda/itda/dto/main/MainInfoDTO.java
@@ -1,20 +1,20 @@
-package com.aolda.itda.dto.main;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-@Builder
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class MainInfoDTO {
-
-    private Long routing;
-    private Long forwarding;
-    private Long certificate;
-
-}
+package com.aolda.itda.dto.main;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class MainInfoDTO {
+
+    private Long routing;
+    private Long forwarding;
+    private Long certificate;
+
+}
diff --git a/src/main/java/com/aolda/itda/entity/certificate/Challenge.java b/src/main/java/com/aolda/itda/entity/certificate/Challenge.java
index 14713bf..41f607e 100644
--- a/src/main/java/com/aolda/itda/entity/certificate/Challenge.java
+++ b/src/main/java/com/aolda/itda/entity/certificate/Challenge.java
@@ -1,5 +1,15 @@
 package com.aolda.itda.entity.certificate;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+@JsonFormat(shape = JsonFormat.Shape.STRING)
 public enum Challenge {
-    HTTP, DNS_CLOUDFLARE
+    HTTP, DNS_CLOUDFLARE;
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
 }
diff --git a/src/main/java/com/aolda/itda/entity/log/Action.java b/src/main/java/com/aolda/itda/entity/log/Action.java
index a620f87..448a65e 100644
--- a/src/main/java/com/aolda/itda/entity/log/Action.java
+++ b/src/main/java/com/aolda/itda/entity/log/Action.java
@@ -1,5 +1,15 @@
 package com.aolda.itda.entity.log;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+@JsonFormat(shape = JsonFormat.Shape.STRING)
 public enum Action {
-    CREATE, UPDATE, DELETE
+    CREATE, UPDATE, DELETE;
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
 }
diff --git a/src/main/java/com/aolda/itda/entity/log/ObjectType.java b/src/main/java/com/aolda/itda/entity/log/ObjectType.java
index 5310315..c91f279 100644
--- a/src/main/java/com/aolda/itda/entity/log/ObjectType.java
+++ b/src/main/java/com/aolda/itda/entity/log/ObjectType.java
@@ -1,5 +1,15 @@
 package com.aolda.itda.entity.log;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+@JsonFormat(shape = JsonFormat.Shape.STRING)
 public enum ObjectType {
-    ROUTING, CERTIFICATE, FORWARDING
+    ROUTING, CERTIFICATE, FORWARDING;
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return name().toLowerCase();
+    }
 }
diff --git a/src/main/java/com/aolda/itda/service/main/MainService.java b/src/main/java/com/aolda/itda/service/main/MainService.java
index 2c36ac8..8a4345e 100644
--- a/src/main/java/com/aolda/itda/service/main/MainService.java
+++ b/src/main/java/com/aolda/itda/service/main/MainService.java
@@ -1,61 +1,61 @@
-package com.aolda.itda.service.main;
-
-import com.aolda.itda.dto.PageResp;
-import com.aolda.itda.dto.auth.IdAndNameDTO;
-import com.aolda.itda.dto.main.MainInfoDTO;
-import com.aolda.itda.repository.certificate.CertificateRepository;
-import com.aolda.itda.repository.forwarding.ForwardingRepository;
-import com.aolda.itda.repository.routing.RoutingRepository;
-import com.aolda.itda.service.AuthService;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import lombok.RequiredArgsConstructor;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-import java.util.Map;
-
-@Service
-@Transactional
-@RequiredArgsConstructor
-public class MainService {
-
-    private final AuthService authService;
-    private final RoutingRepository routingRepository;
-    private final ForwardingRepository forwardingRepository;
-    private final CertificateRepository certificateRepository;
-
-    /* 메인 페이지에 필요한 정보 반환 */
-    public MainInfoDTO getMainInfo(String projectId, List<String> projects) {
-
-        /* 프로젝트 권한 검증 */
-        authService.validateProjectAuth(projects, projectId);
-
-        /* 카운팅 */
-        Long routing = (long) routingRepository.findByProjectIdAndIsDeleted(projectId, false).size();
-        Long forwarding = (long) forwardingRepository.findByProjectIdAndIsDeleted(projectId, false).size();
-        Long certificate = 0L;
-
-        return MainInfoDTO.builder()
-                .routing(routing)
-                .forwarding(forwarding)
-                .certificate(certificate)
-                .build();
-    }
-
-    /* 접근 가능한 프로젝트 조회 */
-    public PageResp<IdAndNameDTO> getAllProjects(Map<String, String> user) throws JsonProcessingException {
-
-        List<IdAndNameDTO> projects;
-        if (authService.isAdmin(user)) {
-            projects = authService.getAllProjects(user.get("token"));
-        }
-
-        else {
-            projects = authService.getProjectsWithUser(user);
-        }
-
-        return PageResp.<IdAndNameDTO>builder()
-                .contents(projects).build();
-    }
-}
+package com.aolda.itda.service.main;
+
+import com.aolda.itda.dto.PageResp;
+import com.aolda.itda.dto.auth.IdAndNameDTO;
+import com.aolda.itda.dto.main.MainInfoDTO;
+import com.aolda.itda.repository.certificate.CertificateRepository;
+import com.aolda.itda.repository.forwarding.ForwardingRepository;
+import com.aolda.itda.repository.routing.RoutingRepository;
+import com.aolda.itda.service.AuthService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Transactional
+@RequiredArgsConstructor
+public class MainService {
+
+    private final AuthService authService;
+    private final RoutingRepository routingRepository;
+    private final ForwardingRepository forwardingRepository;
+    private final CertificateRepository certificateRepository;
+
+    /* 메인 페이지에 필요한 정보 반환 */
+    public MainInfoDTO getMainInfo(String projectId, List<String> projects) {
+
+        /* 프로젝트 권한 검증 */
+        authService.validateProjectAuth(projects, projectId);
+
+        /* 카운팅 */
+        Long routing = (long) routingRepository.findByProjectIdAndIsDeleted(projectId, false).size();
+        Long forwarding = (long) forwardingRepository.findByProjectIdAndIsDeleted(projectId, false).size();
+        Long certificate = 0L;
+
+        return MainInfoDTO.builder()
+                .routing(routing)
+                .forwarding(forwarding)
+                .certificate(certificate)
+                .build();
+    }
+
+    /* 접근 가능한 프로젝트 조회 */
+    public PageResp<IdAndNameDTO> getAllProjects(Map<String, String> user) throws JsonProcessingException {
+
+        List<IdAndNameDTO> projects;
+        if (authService.isAdmin(user)) {
+            projects = authService.getAllProjects(user.get("token"));
+        }
+
+        else {
+            projects = authService.getProjectsWithUser(user);
+        }
+
+        return PageResp.<IdAndNameDTO>builder()
+                .contents(projects).build();
+    }
+}
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
index a8acbee..39e9337 100644
--- a/src/main/resources/logback-spring.xml
+++ b/src/main/resources/logback-spring.xml
@@ -1,90 +1,90 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
-
-    <property name="MAX_FILE_SIZE" value="10MB" />
-    <property name="TOTAL_SIZE" value="1GB" />
-    <property name="MAX_HISTORY" value="30" />
-
-    <!-- 콘솔에 출력할 로그 형식 -->
-    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
-        <encoder>
-            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
-        </encoder>
-    </appender>
-
-    <!-- INFO 로그 파일 저장 (1개당 10MB, 5개까지 유지, 이후 압축) -->
-    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>/data/logs/info.log</file>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <fileNamePattern>/data/logs/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-            <totalSizeCap>${TOTAL_SIZE}</totalSizeCap>
-            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
-                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
-            </timeBasedFileNamingAndTriggeringPolicy>
-        </rollingPolicy>
-        <encoder>
-            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
-        </encoder>
-        <!-- INFO 레벨만 허용 -->
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>INFO</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
-    </appender>
-
-    <!-- WARN 로그 파일 저장 -->
-    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>/data/logs/warn.log</file>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <fileNamePattern>/data/logs/warn.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-            <totalSizeCap>${TOTAL_SIZE}</totalSizeCap>
-            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
-                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
-            </timeBasedFileNamingAndTriggeringPolicy>
-        </rollingPolicy>
-        <encoder>
-            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
-        </encoder>
-        <!-- WARN 레벨만 허용 -->
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>WARN</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
-    </appender>
-
-    <!-- ERROR 로그 파일 저장 -->
-    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
-        <file>/data/logs/error.log</file>
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <fileNamePattern>/data/logs/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
-            <maxHistory>${MAX_HISTORY}</maxHistory>
-            <totalSizeCap>${TOTAL_SIZE}</totalSizeCap>
-            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
-                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
-            </timeBasedFileNamingAndTriggeringPolicy>
-        </rollingPolicy>
-        <encoder>
-            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
-        </encoder>
-        <!-- ERROR 레벨만 허용 -->
-        <filter class="ch.qos.logback.classic.filter.LevelFilter">
-            <level>ERROR</level>
-            <onMatch>ACCEPT</onMatch>
-            <onMismatch>DENY</onMismatch>
-        </filter>
-    </appender>
-
-    <logger name="com.aolda.itda" additivity="false">
-        <!-- 각 Appender 참조 (필터는 Appender 내부에 정의됨) -->
-        <appender-ref ref="INFO_FILE"/>
-        <appender-ref ref="WARN_FILE"/>
-        <appender-ref ref="ERROR_FILE"/>
-        <!-- 콘솔 출력 -->
-        <appender-ref ref="CONSOLE"/>
-    </logger>
-
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+    <property name="MAX_FILE_SIZE" value="10MB" />
+    <property name="TOTAL_SIZE" value="1GB" />
+    <property name="MAX_HISTORY" value="30" />
+
+    <!-- 콘솔에 출력할 로그 형식 -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- INFO 로그 파일 저장 (1개당 10MB, 5개까지 유지, 이후 압축) -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>/data/logs/info.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>/data/logs/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+            <totalSizeCap>${TOTAL_SIZE}</totalSizeCap>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+        <!-- INFO 레벨만 허용 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- WARN 로그 파일 저장 -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>/data/logs/warn.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>/data/logs/warn.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+            <totalSizeCap>${TOTAL_SIZE}</totalSizeCap>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+        <!-- WARN 레벨만 허용 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- ERROR 로그 파일 저장 -->
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>/data/logs/error.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>/data/logs/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
+            <maxHistory>${MAX_HISTORY}</maxHistory>
+            <totalSizeCap>${TOTAL_SIZE}</totalSizeCap>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+        <!-- ERROR 레벨만 허용 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <logger name="com.aolda.itda" additivity="false">
+        <!-- 각 Appender 참조 (필터는 Appender 내부에 정의됨) -->
+        <appender-ref ref="INFO_FILE"/>
+        <appender-ref ref="WARN_FILE"/>
+        <appender-ref ref="ERROR_FILE"/>
+        <!-- 콘솔 출력 -->
+        <appender-ref ref="CONSOLE"/>
+    </logger>
+
 </configuration>
\ No newline at end of file
-- 
GitLab


From 331b11478b712ac7c3fa1dc2794c3881b53d198d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 12:04:32 +0900
Subject: [PATCH 7/9] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=20=EC=82=AC?=
 =?UTF-8?q?=EC=9A=A9=EC=9E=90=20=EA=B2=80=EC=83=89=EC=9D=84=20=EC=9D=BC?=
 =?UTF-8?q?=EB=B6=80=20=EA=B2=80=EC=83=89=EC=9C=BC=EB=A1=9C=20=EB=B3=80?=
 =?UTF-8?q?=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java b/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java
index ceba4b2..19feb19 100644
--- a/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java
+++ b/src/main/java/com/aolda/itda/repository/log/LogQueryDSL.java
@@ -86,7 +86,7 @@ public class LogQueryDSL {
 
         /* 사용자 ID 조건 */
         if (username != null) {
-            builder.and(log.user.keystoneUsername.eq(username));
+            builder.and(log.user.keystoneUsername.contains(username));
         }
 
         /* CUD 조건 */
-- 
GitLab


From 88e8e972827daa6d3b8e7fe1330641e42e8e7a89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 13:20:16 +0900
Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=EC=97=90=20=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=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

---
 .../forwarding/ForwardingController.java      |  5 ++--
 .../controller/routing/RoutingController.java |  5 ++--
 .../forwarding/ForwardingRepository.java      |  4 ++++
 .../repository/routing/RoutingRepository.java |  4 ++++
 .../service/forwarding/ForwardingService.java | 16 ++++++++++---
 .../itda/service/routing/RoutingService.java  | 23 ++++++++++++++++---
 6 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java b/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java
index 36e6f9a..999707a 100644
--- a/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java
+++ b/src/main/java/com/aolda/itda/controller/forwarding/ForwardingController.java
@@ -30,8 +30,9 @@ public class ForwardingController {
     }
 
     @GetMapping("/forwardings")
-    public ResponseEntity<Object> lists(@RequestParam String projectId) {
-        return ResponseEntity.ok(forwardingService.getForwardings(projectId));
+    public ResponseEntity<Object> lists(@RequestParam String projectId,
+                                        @RequestParam(required = false) String query) {
+        return ResponseEntity.ok(forwardingService.getForwardingsWithSearch(projectId, query));
     }
 
     @PatchMapping("/forwarding")
diff --git a/src/main/java/com/aolda/itda/controller/routing/RoutingController.java b/src/main/java/com/aolda/itda/controller/routing/RoutingController.java
index 4b9d551..c96e910 100644
--- a/src/main/java/com/aolda/itda/controller/routing/RoutingController.java
+++ b/src/main/java/com/aolda/itda/controller/routing/RoutingController.java
@@ -31,8 +31,9 @@ public class RoutingController {
     }
 
     @GetMapping("/routings")
-    public ResponseEntity<Object> lists(@RequestParam String projectId) {
-        return ResponseEntity.ok(routingService.getRoutings(projectId));
+    public ResponseEntity<Object> lists(@RequestParam String projectId,
+                                        @RequestParam(required = false) String query) {
+        return ResponseEntity.ok(routingService.getRoutingsWithSearch(projectId, query));
     }
 
     @PatchMapping("/routing")
diff --git a/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java b/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java
index c461762..9a330f0 100644
--- a/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java
+++ b/src/main/java/com/aolda/itda/repository/forwarding/ForwardingRepository.java
@@ -2,6 +2,7 @@ package com.aolda.itda.repository.forwarding;
 
 import com.aolda.itda.entity.forwarding.Forwarding;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 
 import java.util.List;
 import java.util.Optional;
@@ -11,4 +12,7 @@ public interface ForwardingRepository extends JpaRepository<Forwarding, Long> {
     Optional<Forwarding> findByForwardingIdAndIsDeleted(Long forwardingId, Boolean isDeleted);
     Boolean existsByInstanceIpAndInstancePortAndIsDeleted(String instanceIp, String instancePort, Boolean isDeleted);
     Boolean existsByServerPortAndIsDeleted(String serverPort, Boolean isDeleted);
+
+    @Query("SELECT f FROM Forwarding f WHERE f.projectId = ?1 AND f.isDeleted = ?3 AND (f.instanceIp LIKE %?2% OR f.serverPort LIKE %?2% OR f.name LIKE %?2%)")
+    List<Forwarding> findWithSearch(String projectId, String query, Boolean isDeleted);
 }
diff --git a/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java b/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java
index 046296c..44b88ae 100644
--- a/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java
+++ b/src/main/java/com/aolda/itda/repository/routing/RoutingRepository.java
@@ -3,6 +3,7 @@ package com.aolda.itda.repository.routing;
 import com.aolda.itda.entity.forwarding.Forwarding;
 import com.aolda.itda.entity.routing.Routing;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 
 import java.util.List;
 import java.util.Optional;
@@ -11,4 +12,7 @@ public interface RoutingRepository extends JpaRepository<Routing, Long> {
     List<Routing> findByProjectIdAndIsDeleted(String projectId, Boolean isDeleted);
     Optional<Routing> findByRoutingIdAndIsDeleted(Long routingId, Boolean isDeleted);
     Boolean existsByDomainAndIsDeleted(String domain, Boolean isDeleted);
+
+    @Query("SELECT r FROM Routing r WHERE r.projectId = ?1 AND r.isDeleted = ?3 AND (r.domain LIKE %?2% OR r.instanceIp LIKE %?2% OR r.name LIKE %?2%)")
+    List<Routing> findWithSearch(String projectId, String query, Boolean isDeleted);
 }
diff --git a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
index cae38c3..e6fc9d4 100644
--- a/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
+++ b/src/main/java/com/aolda/itda/service/forwarding/ForwardingService.java
@@ -27,6 +27,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.util.List;
+import java.util.regex.Pattern;
 
 @Service
 @Transactional
@@ -52,11 +53,20 @@ public class ForwardingService {
         return forwarding.toForwardingDTO();
     }
 
-    /* 포트포워딩 목록 조회 */
-    public PageResp<ForwardingDTO> getForwardings(String projectId) {
+    /* 포트포워딩 목록 조회 + 검색 */
+    public PageResp<ForwardingDTO> getForwardingsWithSearch(String projectId, String query) {
+
+        /* 입력 검증 */
+        if (query == null || query.isBlank()) {
+            return PageResp.<ForwardingDTO>builder()
+                    .contents(forwardingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                            .stream()
+                            .map(Forwarding::toForwardingDTO)
+                            .toList()).build();
+        }
 
         return PageResp.<ForwardingDTO>builder()
-                .contents(forwardingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                .contents(forwardingRepository.findWithSearch(projectId, query, false)
                         .stream()
                         .map(Forwarding::toForwardingDTO)
                         .toList()).build();
diff --git a/src/main/java/com/aolda/itda/service/routing/RoutingService.java b/src/main/java/com/aolda/itda/service/routing/RoutingService.java
index 769278d..d01eb02 100644
--- a/src/main/java/com/aolda/itda/service/routing/RoutingService.java
+++ b/src/main/java/com/aolda/itda/service/routing/RoutingService.java
@@ -28,6 +28,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.util.List;
+import java.util.regex.Pattern;
 
 @Service
 @Transactional
@@ -52,10 +53,26 @@ public class RoutingService {
         return routing.toRoutingDTO();
     }
 
-    /* Routing 목록 조회 */
-    public PageResp<RoutingDTO> getRoutings(String projectId) {
+    /* Routing 목록 조회 + 검색 */
+    public PageResp<RoutingDTO> getRoutingsWithSearch(String projectId, String query) {
+
+        /* 입력 검증 */
+        if (query == null || query.isBlank()) {
+            return PageResp.<RoutingDTO>builder()
+                    .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                            .stream()
+                            .map(Routing::toRoutingDTO)
+                            .toList()).build();
+        }
+
+        /* 도메인 패턴 검증 */
+        String domainPattern = "^(\\*\\.)?([a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$";
+        if (Pattern.matches(domainPattern, query) && query.startsWith("*.")) {
+            query = query.substring(2);
+        }
+
         return PageResp.<RoutingDTO>builder()
-                .contents(routingRepository.findByProjectIdAndIsDeleted(projectId, false)
+                .contents(routingRepository.findWithSearch(projectId, query, false)
                         .stream()
                         .map(Routing::toRoutingDTO)
                         .toList()).build();
-- 
GitLab


From 9662eda4bf9e66027a5cbe31f55ab3721aa676ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr>
Date: Sat, 29 Mar 2025 13:54:43 +0900
Subject: [PATCH 9/9] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EC=9D=B8?=
 =?UTF-8?q?=ED=84=B0=EC=85=89=ED=84=B0=EC=97=90=EC=84=9C=20=ED=95=84?=
 =?UTF-8?q?=ED=84=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A1=9C?=
 =?UTF-8?q?=EA=B7=B8=EC=97=90=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=A0=95?=
 =?UTF-8?q?=EB=B3=B4=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../{AuthInterceptor.java => AuthFilter.java} | 153 +++++++++---------
 .../com/aolda/itda/config/LoggingFilter.java  |  15 +-
 .../java/com/aolda/itda/config/WebConfig.java |  27 +++-
 3 files changed, 107 insertions(+), 88 deletions(-)
 rename src/main/java/com/aolda/itda/config/{AuthInterceptor.java => AuthFilter.java} (71%)

diff --git a/src/main/java/com/aolda/itda/config/AuthInterceptor.java b/src/main/java/com/aolda/itda/config/AuthFilter.java
similarity index 71%
rename from src/main/java/com/aolda/itda/config/AuthInterceptor.java
rename to src/main/java/com/aolda/itda/config/AuthFilter.java
index fd78fb6..f810c2c 100644
--- a/src/main/java/com/aolda/itda/config/AuthInterceptor.java
+++ b/src/main/java/com/aolda/itda/config/AuthFilter.java
@@ -1,77 +1,76 @@
-package com.aolda.itda.config;
-
-import com.aolda.itda.dto.auth.IdAndNameDTO;
-import com.aolda.itda.exception.CustomException;
-import com.aolda.itda.exception.ErrorCode;
-import com.aolda.itda.service.AuthService;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
-import org.springframework.web.servlet.HandlerInterceptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-@RequiredArgsConstructor
-@Component
-@Slf4j
-public class AuthInterceptor implements HandlerInterceptor {
-
-    private final AuthService authService;
-
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
-        String token = request.getHeader("X-Subject-Token");
-
-        /* 토큰 헤더 검증 */
-        if (token == null || token.isEmpty()) {
-            throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI());
-        }
-
-        /* 유효 토큰 검증 */
-        String userId = authService.validateTokenAndGetUserId(token);
-        if (userId == null) {
-            log.error("Token validation failed for URI {}: {}", request.getRequestURI(), request.getRemoteAddr());
-            throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI());
-        }
-
-        /* 프로젝트 권한 검증 */
-        String projectId = request.getParameter("projectId");
-        if (projectId != null) {
-
-            try {
-                authService.getBestRoleWithinProject(token, projectId).get("role");
-                if (!request.getMethod().equals("GET") && !authService.getBestRoleWithinProject(token, projectId).get("role").equals("admin")) {
-                    throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI());
-
-                }
-            } catch (Exception e) {
-                throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI());
-            }
-
-
-
-        }
-
-        /* 프로젝트 리스트 조회 */
-        List<String> projects;
-        if (authService.isAdmin(Map.of("id", userId, "token", token))) {
-            projects = authService.getAllProjects(token).stream().map(IdAndNameDTO::getId)
-                    .toList();
-        }
-
-        else {
-            projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token))
-                    .stream().map(IdAndNameDTO::getId)
-                    .toList();
-        }
-
-        request.setAttribute("projects", projects);
-        request.setAttribute("user", Map.of("id", userId, "token", token));
-        return true;
-
-    }
-}
+package com.aolda.itda.config;
+
+import com.aolda.itda.dto.auth.IdAndNameDTO;
+import com.aolda.itda.exception.CustomException;
+import com.aolda.itda.exception.ErrorCode;
+import com.aolda.itda.service.AuthService;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+@RequiredArgsConstructor
+@Component
+@Slf4j
+public class AuthFilter extends OncePerRequestFilter {
+
+    private final AuthService authService;
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+
+        if (request.getRequestURI().contains("/api/auth")) {
+            filterChain.doFilter(request, response);
+            return;
+        }
+
+        String token = request.getHeader("X-Subject-Token");
+
+        // 토큰 헤더 검증
+        if (token == null || token.isEmpty()) {
+            throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI());
+        }
+
+        // 유효 토큰 검증
+        String userId = authService.validateTokenAndGetUserId(token);
+        if (userId == null) {
+            log.error("Token validation failed for URI {}: {}", request.getRequestURI(), request.getRemoteAddr());
+            throw new CustomException(ErrorCode.INVALID_TOKEN, request.getRequestURI());
+        }
+
+        // 프로젝트 권한 검증
+        String projectId = request.getParameter("projectId");
+        if (projectId != null) {
+            try {
+                authService.getBestRoleWithinProject(token, projectId).get("role");
+                if (!request.getMethod().equals("GET") && !authService.getBestRoleWithinProject(token, projectId).get("role").equals("admin")) {
+                    throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI());
+                }
+            } catch (Exception e) {
+                throw new CustomException(ErrorCode.UNAUTHORIZED_USER, request.getRequestURI());
+            }
+        }
+
+        // 프로젝트 리스트 조회
+        List<String> projects;
+        if (authService.isAdmin(Map.of("id", userId, "token", token))) {
+            projects = authService.getAllProjects(token).stream().map(IdAndNameDTO::getId).toList();
+        } else {
+            projects = authService.getProjectsWithUser(Map.of("id", userId, "token", token)).stream().map(IdAndNameDTO::getId).toList();
+        }
+
+        request.setAttribute("projects", projects);
+        request.setAttribute("user", Map.of("id", userId, "token", token));
+
+        filterChain.doFilter(request, response);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/aolda/itda/config/LoggingFilter.java b/src/main/java/com/aolda/itda/config/LoggingFilter.java
index f2330bf..8c5c2f0 100644
--- a/src/main/java/com/aolda/itda/config/LoggingFilter.java
+++ b/src/main/java/com/aolda/itda/config/LoggingFilter.java
@@ -1,9 +1,14 @@
 package com.aolda.itda.config;
 
+import com.aolda.itda.exception.CustomException;
+import com.aolda.itda.exception.ErrorCode;
+import com.aolda.itda.service.AuthService;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import jakarta.servlet.FilterChain;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import lombok.RequiredArgsConstructor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -11,11 +16,14 @@ import org.springframework.web.filter.OncePerRequestFilter;
 import org.springframework.web.util.ContentCachingRequestWrapper;
 
 import java.io.IOException;
+import java.util.Map;
 
 @Component
+@RequiredArgsConstructor
 public class LoggingFilter extends OncePerRequestFilter {
 
     private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
+    private final AuthService authService;
 
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -29,15 +37,16 @@ public class LoggingFilter extends OncePerRequestFilter {
         logRequest(cachingRequest);
     }
 
-    private void logRequest(ContentCachingRequestWrapper request) {
+    private void logRequest(ContentCachingRequestWrapper request) throws JsonProcessingException {
         String ip = request.getRemoteAddr();
         String method = request.getMethod();
         String uri = request.getRequestURI();
         String queryString = request.getQueryString();
         String body = getRequestBody(request);
+        Map<String, String> user = (Map<String, String>) request.getAttribute("user");
 
-        logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, Request Body: {}",
-                ip, method, uri, (queryString != null ? queryString : "None"),
+        logger.info("IP: {}, Method: {}, URI: {}, Query Params: {}, User: {}, Request Body: {}",
+                ip, method, uri, (queryString != null ? queryString : "None"), (user != null ? user.get("id") : "None"),
                 (!body.isEmpty() ? body : "None"));
     }
 
diff --git a/src/main/java/com/aolda/itda/config/WebConfig.java b/src/main/java/com/aolda/itda/config/WebConfig.java
index e3893ae..a3559c4 100644
--- a/src/main/java/com/aolda/itda/config/WebConfig.java
+++ b/src/main/java/com/aolda/itda/config/WebConfig.java
@@ -3,17 +3,18 @@ package com.aolda.itda.config;
 import com.querydsl.jpa.impl.JPAQueryFactory;
 import jakarta.persistence.EntityManager;
 import lombok.RequiredArgsConstructor;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 @Configuration
 @RequiredArgsConstructor
 public class WebConfig implements WebMvcConfigurer {
 
-    private final AuthInterceptor authInterceptor;
+    private final AuthFilter authFilter;
+    private final LoggingFilter loggingFilter;
 
     @Override
     public void addCorsMappings(CorsRegistry registry) { // 스프링단에서 cors 설정
@@ -26,13 +27,23 @@ public class WebConfig implements WebMvcConfigurer {
         ;
     }
 
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        String[] excludeAuth = {"/error", "/api/auth/*" };
 
-        registry.addInterceptor(authInterceptor)
-                .addPathPatterns("/**")
-                .excludePathPatterns(excludeAuth);
+    @Bean
+    public FilterRegistrationBean<AuthFilter> authFilterRegistration() {
+        FilterRegistrationBean<AuthFilter> registrationBean = new FilterRegistrationBean<>();
+        registrationBean.setFilter(authFilter);
+        registrationBean.setOrder(1); // AuthFilter의 순서를 1로 설정
+        registrationBean.addUrlPatterns("/*");
+        return registrationBean;
+    }
+
+    @Bean
+    public FilterRegistrationBean<LoggingFilter> loggingFilterRegistration() {
+        FilterRegistrationBean<LoggingFilter> registrationBean = new FilterRegistrationBean<>();
+        registrationBean.setFilter(loggingFilter);
+        registrationBean.setOrder(2); // LoggingFilter의 순서를 2로 설정
+        registrationBean.addUrlPatterns("/*");
+        return registrationBean;
     }
 
     @Bean
-- 
GitLab