hmkim 03-24
250324 김혜민 jwt관련 리팩토링
@bbc6a5b974c7accd97c083712c0af477577220ac
src/main/java/com/takensoft/cms/mber/service/Impl/RefreshTokenServiceImpl.java
--- src/main/java/com/takensoft/cms/mber/service/Impl/RefreshTokenServiceImpl.java
+++ src/main/java/com/takensoft/cms/mber/service/Impl/RefreshTokenServiceImpl.java
@@ -80,12 +80,12 @@
             return result;
         }
         try {
-            jwtUtil.isExpired(refreshToken);
+            jwtUtil.getClaim(refreshToken, "isExpired");
         } catch (ExpiredJwtException e) {
             result.put("result", 0);
             return result;
         }
-        String category = jwtUtil.getCategory(refreshToken);
+        String category = (String) jwtUtil.getClaim(refreshToken, "category");
         if(!category.equals("refresh")) {
             result.put("result", 0);
             return result;
@@ -145,7 +145,7 @@
             //res.addCookie(jwtUtil.createCookie("refresh",null, 0));
 
             RefreshVO refreshVO = new RefreshVO();
-            refreshVO.setMbrId(jwtUtil.getMbrId(refreshTokenCheck(req).get("refreshToken").toString()));
+            refreshVO.setMbrId((String) jwtUtil.getClaim(refreshTokenCheck(req).get("refreshToken").toString(), "mbrId"));
 
             //중복로그인 비허용시 삭제
             if (!redisConfig.isAllowMultipleLogin()) {
@@ -177,7 +177,7 @@
 
             String refreshToken = refreshTokenCheck(req).get("refreshToken").toString();
 
-            String userId = jwtUtil.getMbrId(refreshToken);
+            String userId = (String) jwtUtil.getClaim(refreshToken, "mbrId");
 
             // 중복 로그인 비허용 체크 (DB에 저장된 리프레시 토큰과 비교)
             if (!redisConfig.isAllowMultipleLogin()) {
@@ -189,16 +189,16 @@
                 }
             }
 
-            Date expired = jwtUtil.getExpired(refreshToken);
+            Date expired = (Date) jwtUtil.getClaim(refreshToken, "Expired");
 
             // 만료시간과 현재 시간의 차이 계산
             long timeDffrnc = (expired.getTime() - new Date().getTime()) / (1000 * 60 * 60);
 
             MberVO mber = new MberVO();
-            List<MberAuthorVO> roles = jwtUtil.getRoles(refreshToken);
-            mber.setLgnId(jwtUtil.getLgnId(refreshToken));
-            mber.setMbrId(jwtUtil.getMbrId(refreshToken));
-            mber.setMbrNm(jwtUtil.getMbrNm(refreshToken));
+            List<MberAuthorVO> roles = (List<MberAuthorVO>) jwtUtil.getClaim(refreshToken, "roles");
+            mber.setLgnId((String) jwtUtil.getClaim(refreshToken, "lgnId"));
+            mber.setMbrId((String) jwtUtil.getClaim(refreshToken, "mbrId"));
+            mber.setMbrNm((String) jwtUtil.getClaim(refreshToken, "mbrNm"));
             mber.setAuthorList(roles);
             // 신규 AccessToken 발행
             String newAccessToken = jwtUtil.createJwt("Authorization", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_ACCESSTIME);
src/main/java/com/takensoft/common/HierachyVO.java
--- src/main/java/com/takensoft/common/HierachyVO.java
+++ src/main/java/com/takensoft/common/HierachyVO.java
@@ -7,37 +7,26 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
+/**
+ * @author takensoft
+ * @since 2025.01.22
+ * @modification
+ *     since    |    author    | description
+ *  2025.01.22  |  takensoft   | 최초 등록
+ *
+ * 최상위 코드 VO
+ */
 @Setter
 @Getter
 @NoArgsConstructor
 @AllArgsConstructor
 public class HierachyVO {
 
-    /**
-     * 공통으로 사용될 아이디
-     */
-    private String id;
-    /**
-     * 공통으로 사용될 상위 아이디
-     */
-    private String upId;
-    /**
-     * 공통으로 사용될 이름
-     */
-    private String nm;
-    /**
-     * 공통으로 사용될 깊이(레벨)
-     */
-    private int grd;
-    /**
-     * 공통으로 사용될 순서
-     */
-    private int sn;
-
-    /**
-     * 공통으로 사용될 자식 객체
-     */
-    List<HierachyVO> childList = new ArrayList<HierachyVO>();
+    private String id;                                  // 공통으로 사용될 아이디
+    private String upId;                                // 공통으로 사용될 상위 아이디
+    private String nm;                                  // 공통으로 사용될 이름
+    private int grd;                                    // 공통으로 사용될 깊이(레벨)
+    private int sn;                                     // 공통으로 사용될 순서
+    List<HierachyVO> childList = new ArrayList<HierachyVO>();    // 공통으로 사용될 자식 객체
 
 }
src/main/java/com/takensoft/common/Pagination.java
--- src/main/java/com/takensoft/common/Pagination.java
+++ src/main/java/com/takensoft/common/Pagination.java
@@ -5,7 +5,15 @@
 
 import java.util.HashMap;
 import java.util.Map;
-
+/**
+ * @author takensoft
+ * @since 2025.01.22
+ * @modification
+ *     since    |    author    | description
+ *  2025.01.22  |  takensoft   | 최초 등록
+ *
+ * 페이징
+ */
 @Getter
 @Setter
 public class Pagination {
src/main/java/com/takensoft/common/config/AppConfig.java (Renamed from src/main/java/com/takensoft/common/config/CommonConfig.java)
--- src/main/java/com/takensoft/common/config/CommonConfig.java
+++ src/main/java/com/takensoft/common/config/AppConfig.java
@@ -22,7 +22,7 @@
  * 기본 설정을 위한 Config
  */
 @Configuration
-public class CommonConfig {
+public class AppConfig {
 
     /**
      * @return MappingJackson2JsonView - JSON 응답을 위한 뷰 객체
src/main/java/com/takensoft/common/config/SecurityConfig.java
--- src/main/java/com/takensoft/common/config/SecurityConfig.java
+++ src/main/java/com/takensoft/common/config/SecurityConfig.java
@@ -50,7 +50,7 @@
     private final CustomAuthenticationEntryPoint authenticationEntryPoint;
     private final CustomAccessDenieHandler accessDenieHandler;
     private final HttpRequestUtil httpRequestUtil;
-    private final CommonConfig commonConfig;
+    private final AppConfig appConfig;
     private final RedisConfig redisConfig;
 
     private static String FRONT_URL;    // 프론트 접근 허용 URL
@@ -73,7 +73,7 @@
      *
      * SecurityConfig 생성자
      */
-    public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, AccesCtrlService accesCtrlService, CommonConfig commonConfig, RedisConfig redisConfig,
+    public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, AccesCtrlService accesCtrlService, AppConfig appConfig, RedisConfig redisConfig,
                           LgnHstryService lgnHstryService, CustomAuthenticationEntryPoint authenticationEntryPoint, CustomAccessDenieHandler accessDenieHandler, HttpRequestUtil httpRequestUtil,
                           @Value("${front.url}")String fUrl, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate) {
 
@@ -85,7 +85,7 @@
         this.accessDenieHandler = accessDenieHandler;
         this.jwtUtil = jwtUtil;
         this.httpRequestUtil = httpRequestUtil;
-        this.commonConfig = commonConfig;
+        this.appConfig = appConfig;
         this.redisConfig = redisConfig;
 
         this.FRONT_URL = fUrl;
@@ -170,10 +170,10 @@
             http.addFilterBefore(new JWTFilter(jwtUtil, commonConfig, redisConfig, redisTemplate), LoginFilter.class); // JWT 인증 필터 추가
         }*/
 
-        http.addFilterBefore(new JWTFilter(jwtUtil, commonConfig, redisConfig, redisTemplate), LoginFilter.class); // 토큰 검증 필터
-        http.addFilterBefore(new AccesFilter(accesCtrlService, httpRequestUtil, commonConfig), JWTFilter.class); // 아이피 검증
+        http.addFilterBefore(new JWTFilter(jwtUtil, appConfig, redisConfig, redisTemplate), LoginFilter.class); // 토큰 검증 필터
+        http.addFilterBefore(new AccesFilter(accesCtrlService, httpRequestUtil, appConfig), JWTFilter.class); // 아이피 검증
         http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService, lgnHstryService, httpRequestUtil,
-                        commonConfig,redisConfig, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME, redisTemplate), UsernamePasswordAuthenticationFilter.class); // 로그인 필터
+                appConfig,redisConfig, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME, redisTemplate), UsernamePasswordAuthenticationFilter.class); // 로그인 필터
 
         return http.build();
     }
src/main/java/com/takensoft/common/config/WebConfig.java
--- src/main/java/com/takensoft/common/config/WebConfig.java
+++ src/main/java/com/takensoft/common/config/WebConfig.java
@@ -17,6 +17,7 @@
  */
 @Configuration
 public class WebConfig {
+
     /**
      * @return ForwardedHeaderFilter
      *
src/main/java/com/takensoft/common/filter/AccesFilter.java
--- src/main/java/com/takensoft/common/filter/AccesFilter.java
+++ src/main/java/com/takensoft/common/filter/AccesFilter.java
@@ -2,7 +2,7 @@
 
 import com.takensoft.cms.accesCtrl.service.AccesCtrlService;
 import com.takensoft.cms.accesCtrl.vo.AccesCtrlVO;
-import com.takensoft.common.config.CommonConfig;
+import com.takensoft.common.config.AppConfig;
 import com.takensoft.common.util.HttpRequestUtil;
 import com.takensoft.common.util.ErrorResponse;
 import org.springframework.http.HttpStatus;
@@ -17,10 +17,14 @@
 import java.io.IOException;
 import java.time.LocalDateTime;
 import java.util.List;
-
 /**
  * @author takensoft
  * @since 2024.04.15
+ * @modification
+ *     since    |    author    | description
+ *  2024.04.15  |  takensoft   | 최초 등록
+ *
+ * OncePerRequestFilter - 한 번의 요청마다 단 한 번만 필터링 작업을 수행하는 필터를 제공하는 클래스
  *
  * Access(아이피) 검증 필터
  */
@@ -28,14 +32,29 @@
 
     private final AccesCtrlService accesCtrlService;
     private final HttpRequestUtil httpRequestUtil;
-    private final CommonConfig commonConfig;
+    private final AppConfig appConfig;
 
-    public AccesFilter(AccesCtrlService accesCtrlService, HttpRequestUtil httpRequestUtil, CommonConfig commonConfig) {
+    /**
+     * @param accesCtrlService 접근 제어 관련 인터페이스의 인스턴스
+     * @param httpRequestUtil HTTP 요청 관련 유틸리티 클래스의 인스턴스
+     * @param appConfig 기본 설정을 위한 Config
+     *
+     * AccesFilter 생성자
+     */
+    public AccesFilter(AccesCtrlService accesCtrlService, HttpRequestUtil httpRequestUtil, AppConfig appConfig) {
         this.accesCtrlService = accesCtrlService;
         this.httpRequestUtil = httpRequestUtil;
-        this.commonConfig = commonConfig;
+        this.appConfig = appConfig;
     }
-
+    /**
+     * @param request HttpServletRequest 객체
+     * @param response HttpServletResponse 객체
+     * @param filterChain 필터 체인을 통해 다음 필터로 요청을 전달
+     * @throws ServletException 필터 처리 중 발생한 서블릿 예외
+     * @throws IOException 필터 처리 중 발생한 IO 예외
+     *
+     * Access(아이피) 검증
+     */
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
         try {
@@ -60,7 +79,7 @@
             // 응답 헤더 설정 및 json 응답 전송
             response.setContentType(MediaType.APPLICATION_JSON_VALUE);
             response.setStatus(HttpStatus.FORBIDDEN.value());
-            response.getOutputStream().write(commonConfig.getObjectMapper().writeValueAsBytes(errorResponse));
+            response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse));
         } catch (Exception e) {
             // 시스템 에러 발생
             e.printStackTrace();
@@ -74,11 +93,16 @@
             // 응답 헤더 설정 및 json 응답 전송
             response.setContentType(MediaType.APPLICATION_JSON_VALUE);
             response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
-            response.getOutputStream().write(commonConfig.getObjectMapper().writeValueAsBytes(errorResponse));
+            response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse));
         }
     }
 
-    // 요청 URI에 따른 접근 제어 확인
+    /**
+     * @param accesCtrlList 접근 제어 정보 리스트
+     * @param req HttpServletRequest 객체
+     * @return boolean 요청 URI에 따른 접근 제어 여부
+     * 요청 URI에 따른 접근 제어 확인
+     */
     private boolean isAccesCntrl(List<AccesCtrlVO> accesCtrlList, HttpServletRequest req) {
         for(AccesCtrlVO vo : accesCtrlList) {
             AntPathRequestMatcher matcher = new AntPathRequestMatcher(vo.getCntrlCrs());
src/main/java/com/takensoft/common/filter/JWTFilter.java
--- src/main/java/com/takensoft/common/filter/JWTFilter.java
+++ src/main/java/com/takensoft/common/filter/JWTFilter.java
@@ -2,7 +2,7 @@
 
 import com.takensoft.cms.mber.vo.MberAuthorVO;
 import com.takensoft.cms.mber.vo.MberVO;
-import com.takensoft.common.config.CommonConfig;
+import com.takensoft.common.config.AppConfig;
 import com.takensoft.common.config.RedisConfig;
 import com.takensoft.common.util.ErrorResponse;
 import com.takensoft.common.util.JWTUtil;
@@ -38,7 +38,7 @@
 public class JWTFilter extends OncePerRequestFilter {
 
     private final JWTUtil jwtUtil;
-    private final CommonConfig commonConfig;
+    private final AppConfig appConfig;
     private final RedisConfig redisConfig;
     private final RedisTemplate<String, String> redisTemplate;
     /**
@@ -46,9 +46,9 @@
      *
      * JWTFilter 생성자
      */
-    public JWTFilter(JWTUtil jwtUtil, CommonConfig commonConfig, RedisConfig redisConfig, RedisTemplate<String, String> redisTemplate) {
+    public JWTFilter(JWTUtil jwtUtil, AppConfig appConfig, RedisConfig redisConfig, RedisTemplate<String, String> redisTemplate) {
         this.jwtUtil = jwtUtil;
-        this.commonConfig = commonConfig;
+        this.appConfig = appConfig;
         this.redisConfig = redisConfig;
         this.redisTemplate = redisTemplate;
     }
@@ -73,7 +73,7 @@
             }
 
             // 토큰 만료 여부 검증
-            if(jwtUtil.isExpired(accessToken)) {
+            if( (Boolean) jwtUtil.getClaim(accessToken, "isExpired")) {
                 throw new JwtException("Token expired");
             }
             // 토큰에서 페이로드 확인[ 발급시 명시 ]
@@ -87,7 +87,7 @@
             );
 
             // 중복 로그인 비허용 설정이면 Redis에서 최신 JWT 가져와 비교
-            String userId = jwtUtil.getMbrId(accessToken);
+            String userId = (String) jwtUtil.getClaim(accessToken, "mbrId");
             if (!redisConfig.isAllowMultipleLogin()) {
                 String storedToken = redisTemplate.opsForValue().get("jwt:" + userId);
                 if (storedToken == null) {
@@ -107,7 +107,7 @@
                     // 응답 헤더 설정 및 json 응답 전송
                     response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                     response.setStatus(HttpStatus.UNAUTHORIZED.value());
-                    response.getOutputStream().write(commonConfig.getObjectMapper().writeValueAsBytes(errorResponse));
+                    response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse));
                     return;
                 }
             }
@@ -133,7 +133,7 @@
             // 응답 헤더 설정 및 json 응답 전송
             response.setContentType(MediaType.APPLICATION_JSON_VALUE);
             response.setStatus(HttpStatus.UNAUTHORIZED.value());
-            response.getOutputStream().write(commonConfig.getObjectMapper().writeValueAsBytes(errorResponse));
+            response.getOutputStream().write(appConfig.getObjectMapper().writeValueAsBytes(errorResponse));
         }
     }
 }
(파일 끝에 줄바꿈 문자 없음)
src/main/java/com/takensoft/common/filter/LoginFilter.java
--- src/main/java/com/takensoft/common/filter/LoginFilter.java
+++ src/main/java/com/takensoft/common/filter/LoginFilter.java
@@ -7,7 +7,7 @@
 import com.takensoft.cms.mber.vo.LgnHstryVO;
 import com.takensoft.cms.mber.vo.MberVO;
 import com.takensoft.cms.mber.vo.RefreshVO;
-import com.takensoft.common.config.CommonConfig;
+import com.takensoft.common.config.AppConfig;
 import com.takensoft.common.config.RedisConfig;
 import com.takensoft.common.exception.FilterExceptionHandler;
 import com.takensoft.common.util.HttpRequestUtil;
@@ -49,7 +49,7 @@
     private final RefreshTokenService refreshTokenService;
     private final LgnHstryService lgnHstryService;
     private final HttpRequestUtil httpRequestUtil;
-    private final CommonConfig commonConfig;
+    private final AppConfig appConfig;
     private final RedisConfig redisConfig;
 
     private static long JWT_ACCESSTIME; // access 토큰 유지 시간
@@ -67,13 +67,13 @@
      * LoginFilter 생성자
      */
     public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, LgnHstryService lgnHstryService, HttpRequestUtil httpRequestUtil,
-                       CommonConfig commonConfig, RedisConfig redisConfig, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate) {
+                       AppConfig appConfig, RedisConfig redisConfig, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate) {
         this.authenticationManager = authenticationManager;
         this.jwtUtil = jwtUtil;
         this.refreshTokenService = refreshTokenService;
         this.lgnHstryService = lgnHstryService;
         this.httpRequestUtil = httpRequestUtil;
-        this.commonConfig = commonConfig;
+        this.appConfig = appConfig;
         this.redisConfig = redisConfig;
 
         this.JWT_ACCESSTIME = aTime;
src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
--- src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
+++ src/main/java/com/takensoft/common/filter/SessionAuthFilter.java
@@ -24,13 +24,26 @@
 
     private final JWTUtil jwtUtil;
 
+    /**
+     * @param jwtUtil JWT 유틸리티 클래스의 인스턴스
+     *
+     * 세션 Filter 생성자
+     */
     public SessionAuthFilter(JWTUtil jwtUtil) {
         this.jwtUtil = jwtUtil;
     }
 
+    /**
+     * @param request HttpServletRequest 객체
+     * @param response HttpServletResponse 객체
+     * @param filterChain 필터 체인을 통해 다음 필터로 요청을 전달
+     * @throws ServletException 필터 처리 중 발생한 서블릿 예외
+     * @throws IOException 필터 처리 중 발생한 IO 예외
+     *
+     * 세션 Filter 검증
+     */
     @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-            throws ServletException, IOException {
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  throws ServletException, IOException {
 /*
         // 현재 로그인 방식 확인
         if (!"SESSION".equals(authConfig.getLoginType())) {
src/main/java/com/takensoft/common/util/HttpRequestUtil.java
--- src/main/java/com/takensoft/common/util/HttpRequestUtil.java
+++ src/main/java/com/takensoft/common/util/HttpRequestUtil.java
@@ -19,6 +19,13 @@
 public class HttpRequestUtil {
 
     /**
+     * 기본 생성자
+     */
+    private HttpRequestUtil() {
+
+    }
+
+    /**
      * @param req - HTTP 요청 객체
      * @return 클라이언트 IP 주소 (String)
      * @throws UnknownHostException - 로컬 IP 주소를 확인할 수 없는 경우
src/main/java/com/takensoft/common/util/JWTUtil.java
--- src/main/java/com/takensoft/common/util/JWTUtil.java
+++ src/main/java/com/takensoft/common/util/JWTUtil.java
@@ -80,52 +80,6 @@
         cookie.setHttpOnly(true); // front에서 script로 접근 방지
         return cookie;
     }
-
-    public String getCategory(String token) {
-        return Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload().get("category", String.class);
-    }
-
-    // 접속자 토큰 기반 회원 아이디 추출
-    public String getMbrId(String token) {
-        return Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload().get("mbrId", String.class);
-    }
-
-    // 접속자 토큰 기반 로그인 아이디 추출
-    public String getLgnId(String token) {
-        return Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload().get("lgnId", String.class);
-    }
-
-    // 접속자 토큰 기반 회원명 추출
-    public String getMbrNm(String token) {
-        return Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload().get("mbrNm", String.class);
-    }
-
-    // 접속자 토큰 기반 권한정보 추출
-    public List<MberAuthorVO> getRoles(String token) {
-        // 토큰에서 권한 정보를 가져옴
-        Claims claims = Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload();
-        List<HashMap> roles = claims.get("roles", List.class);
-        List<MberAuthorVO> authorList = new ArrayList<MberAuthorVO>();
-        if (roles != null && !roles.isEmpty()) {
-            for(Map role : roles) {
-                MberAuthorVO mberAuthor = new MberAuthorVO();
-                mberAuthor.setAuthrtCd(role.get("authority").toString());
-                authorList.add(mberAuthor);
-            }
-        }
-        return authorList;
-    }
-
-    // 토큰 소멸 여부
-    public Boolean isExpired(String token) {
-        return Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload().getExpiration().before(new Date());
-    }
-
-    // 토큰 만료 시간
-    public Date getExpired(String token) {
-        return Jwts.parser().verifyWith(JWT_SECRET_KEY).build().parseSignedClaims(token).getPayload().getExpiration();
-    }
-    
     // 로그인 사용자 아이디 조회
     public String getWriter() {
         String mbrId = null;
@@ -136,9 +90,6 @@
         }
         return mbrId;
     }
-
-
-
 
     /**
      * @param tkn JWT 토큰 문자열
Add a comment
List