📝오늘 공부한 것
- 실전프로젝트 - '행동대장' 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
'TIL(Today I Learned)' 카테고리의 다른 글
TIL-230905(항해99 실전 프로젝트-행동대장(25)) (0) | 2023.09.05 |
---|---|
TIL-230904(항해99 실전 프로젝트-행동대장(24)) (0) | 2023.09.04 |
TIL-230901(항해99 실전 프로젝트-행동대장(22)) (0) | 2023.09.01 |
TIL-230831(항해99 실전 프로젝트-행동대장(21)) (0) | 2023.08.31 |
TIL-230830(항해99 실전 프로젝트-행동대장(20)) (0) | 2023.08.30 |