✨ TaskFlow Trouble Shooting

이동근·2025년 6월 19일

Mini Project

목록 보기
6/8
post-thumbnail

☘️ TaskFlow Trouble Shootiing

  • 맡은 부분 :회원가입, 로그인, JWT, 예외처리, (CORS,Filter) 설정,

    • Spring Security 사용하지 않음

💫 설정 문제

  • window 운영체제에서 관리자 권한으로 Intellij를 시작하지 않을 경우 권한이 없어 프로젝트가 실행 되지 않는 상황이 발생

    -VM Option 설정을 해주거나, Intellij를 관리자 권한으로 실행 시 해결


💫 406 Error (회원가입, 로그인)

  • 회원가입, 로그인 로직 작성 후 PostMan 사용 실행 → 406 Error 발생

    • OffsetDateTime 타입으로 데이터를 반환이 원인

      • Jackson 이 Java 8 날짜/시간을 이해하지 못하기 때문에, 직렬화/역직렬화가 불가능
    • 의존성을 추가하여 해결

build-gradle

implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'

💫 JWT

  • JWT Util, JWT Filter 로직 예외 처리

    • Controller 영역에서는 @ControllerAdvice를 사용해서 공통 예외처리를 사용하여 예외처리를 해결

    • Filter에서 발생하는 예외는 @ControllerAdvice를 사용한 컨트룰러에서 해결이 불가

      • @ControllerAdvice에 도달하기 전에 Filter에서 먼저 예외가 발생
[1] Filter
    ↓
[2] DispatcherServlet
    ↓
[3] Controller
    ↓
[4] 응답 중 예외 발생 시 -> ControllerAdvice의 @ExceptionHandler
    ↓
[5] ViewResolver or ResponseBody 처리
    ↓
[6] 응답 반환
  • Filter에서 원하는 응답 형태로 수동으로 직접 작성

    • Jwt Filter 내부에 공통 에러 응답 메서드를 생성 후 예외가 발생하는 곳에 적용

    • Jwt Util에서 try-catch를 사용하여 다양한 예외에 대해 정리

      • return문을 사용하지 않을경우 오류 발생

JwtUtil

public String validateToken(String token){
        try {
            Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token);
            return null; // 유효함
        } catch (SecurityException | MalformedJwtException e) {
            return "유효하지 않은 JWT 서명입니다.";
        } catch (ExpiredJwtException e) {
            return "만료된 JWT 토큰입니다.";
        } catch (UnsupportedJwtException e) {
            return "지원되지 않는 JWT 토큰입니다.";
        } catch (IllegalArgumentException e) {
            return "잘못된 JWT 토큰입니다.";
        }
    }

공통 에러 응답 메서드

// 공통 에러 응답 처리
    private void errorResponse(HttpServletResponse response, int status, String message) throws IOException {
        response.setStatus(status);
        response.setContentType("application/json;charset=utf-8");

        String json = "{" +
                "\"success\" : false," +
                "\"message\": \""+ message + "\"," +
                "\"data\" : null," +
                "\"timestamp\" : \"" + OffsetDateTime.now() + "\"" +
                "}";

        response.getWriter().write(json);
    }

JwtFilter 예외 발생 적용

		// 토큰 존재 유무 확인
        if(authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")){
            errorResponse(response,HttpServletResponse.SC_UNAUTHORIZED,"인증이 필요합니다");
            return;
        }

        // "Bearer" 빼고 확인
        String jwt = authorizationHeader.substring(7);

        // 토큰 검증
        String errorMessage = jwtUtil.validateToken(jwt);
        if (errorMessage != null) {
            errorResponse(response, HttpServletResponse.SC_FORBIDDEN, errorMessage);
            return;
        }

💫 CORS 연결

  • 프론트엔드 연결을 위해 docker를 실행 → localhost:3100 연결

  • 백엔드 연결을 위해 Intellij을 실행 → localhost:8080 연결

  • 웹페이지에서 데이터 입력 후 실행 → CORS 오류 발생

    • 프론트엔드와 백엔드 연결이 되지 않아 문제 발생

    • Intellij에서 CORS를 설정

      • 1번째 필터여야함 →setOrder(0)

      • WebMvcConfigurer 상속하는 클래스에서 적용

WebConfig

@Bean
    public FilterRegistrationBean<CorsFilter> corsFilter(){

        CorsConfiguration config = new CorsConfiguration();
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        // 도메인 설정
        config.setAllowedOriginPatterns(List.of(
                "http://localhost:3100"
        ));

        // HTTP 메서드 설정
        config.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));

        // 헤더 설정
        config.setAllowedHeaders(List.of("*"));

        // 응답 헤더
        config.setExposedHeaders(List.of(
                "Authorization",
                "Content-Type"
        ));

        // 인증 정보 허용
        config.setAllowCredentials(true);

        // 모든 경로에 설정 적용
        source.registerCorsConfiguration("/**", config);

        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));

        bean.setOrder(0);

        return bean;
    }
profile
안녕하세요

0개의 댓글