본문 바로가기

TIL(Today I Learned)

TIL-230902(항해99 실전 프로젝트-행동대장(23))

728x90

📝오늘 공부한 것

  • 실전프로젝트 - '행동대장' CORS에러 해결

 

⛔문제점

[프론트에러 메시지]

Access to XMLHttpRequest at 'https://~~백엔드 주소~~:8080/api/posts/177' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. :3000/detail/178:1 Access to XMLHttpRequest at 'https://~~백엔드 주소~~::8080/api/posts/178' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

-> 로그인 후 발급된 access token으로 요청할 경우 잘 작동함. 그러나 만료된 access token으로 요청할 경우 CORS에러가 발생함.

 

시도해 본 것들💦

access token이 만료되었을 때 상태코드 403에러가 떠야하는데 CORS에러가 났다. 그래서 혹시나 filter에서 무언가 막혀서 에러가 나는 건가,,response를 제대로 전달해주지 않아서 나는 건가 해서 filter에 response를 추가하였다.

 

 JwtAuthorizationFilter

   @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
        String accessTokenValue = jwtUtil.getJwtFromHeader(req, AUTHORIZATION_ACCESS);

        log.info("Access token value: {}", accessTokenValue);

        if (StringUtils.hasText(accessTokenValue)) {

            if (!jwtUtil.validateAccessToken(accessTokenValue)) {
                log.error("Token Error");

                // 유효하지 않은 토큰에 대한 커스텀 응답
                ErrorResponse errorResponse = new ErrorResponse("유효하지 않은 토큰입니다.");
                sendErrorResponse(res, HttpStatus.FORBIDDEN, errorResponse);
                return;
            }

            Claims info = jwtUtil.getUserInfoFromAccessToken(accessTokenValue);

            try {
                setAuthentication(info.getSubject());
            } catch (Exception e) {
                log.error(e.getMessage());

                // 예외에 대한 커스텀 응답
                ErrorResponse errorResponse = new ErrorResponse("서버 오류입니다.");
                sendErrorResponse(res, HttpStatus.INTERNAL_SERVER_ERROR, errorResponse);
                return;
            }
        }

        filterChain.doFilter(req, res);
    }

    private void sendErrorResponse(HttpServletResponse response, HttpStatus httpStatus, ErrorResponse errorResponse) throws IOException {
        response.setStatus(httpStatus.value());
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonErrorResponse = objectMapper.writeValueAsString(errorResponse);
        response.getWriter().write(jsonErrorResponse);
    }

 

그래도 여전히 해결되지 않은 CORS 에러....

 

💯해결

WebMvcConfig에 CORS 설정도 해놓았었고, 로그인 후 발급된 access token도 잘 되었기 때문에 뭐가 문제인지 찾지 못했다.

그런데 security filter에서 추가로 cors 설정을 해줘야했던 것이었다!!

 

 WebSecurityConfig

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // CSRF 설정
        http.cors(withDefaults())
                .csrf((csrf) -> csrf.disable());

        http.sessionManagement((sessionManagement) ->
                sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        );

        http.authorizeHttpRequests((authorizeHttpRequests) ->
                authorizeHttpRequests
                        .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
                        .requestMatchers("/").permitAll()
                        .requestMatchers("/api/auth/**").permitAll()
                        .requestMatchers(HttpMethod.GET, "/api/**").permitAll()
                        .requestMatchers(HttpMethod.OPTIONS, "/api/**").permitAll()
                        .anyRequest().authenticated()
        );

        // 필터 관리
        http.addFilterBefore(jwtAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

.cors(withDefaults())를 추가해주니 바로 해결되었다!!

 

 

https://docs.spring.io/spring-security/reference/5.7/servlet/integrations/cors.html#page-title

 

CORS :: Spring Security

 

docs.spring.io

https://stackoverflow.com/questions/59760003/enabling-cross-origin-requests-spring-boot

 

Enabling Cross Origin Requests Spring Boot

I'm developing an application which consists of a backend application developed with Spring Boot and a frontend application developed with Angular 8. Now I want to enable Cross Origin to let the

stackoverflow.com

728x90