문제 발생
프로젝트 진행 중 프론트엔드 분들을 위한 Mock-up data API를 만들어 EC2를 활용해 배포하여 제공하게 되었는데 이때 Cors 문제가 발생하게 되었다.
스프링 시큐리티를 사용하지 않으므로 간단하게 컨트롤러에 @CrossOrigin 에너테이션으로 해결할 수 있을줄 알았지만 계속해서 http status 415 에러가 난다는 보고를 받았다.
문제 해결
이를 해결하기 위해 Cors filter를 직접 작성해 주기로 했다.
package com.stub_data_server.cors;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter { // javax.servlet의 Filter 구현
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:3000"); //"*" 와일드 카드 사용 불가
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods","*");
response.setHeader("Access-Control-Max-Age", "1000000");
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization");
// 클라이언트에서 response header의 특정 필드에 접근하기 위해서
// "Access-Control-Expose-Headers"를 설정해 주어야 한다.
response.setHeader("Access-Control-Expose-Headers", "authorization, refresh");
response.setHeader("authorization", "bearer qnwjdnqwjkndjkqnwkjdnwqkjndjkqnwjdknqjwdvnmjwqnjvw");
response.setHeader("refresh", "kqwdkjbqkjwbndjkqnvjqennoqenvqnqnmwkmdqkmwqldkml");
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
}else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
}
Spring Security
스프링 시큐리티를 사용한다면 CorsConfiguration을 사용하여 커스텀 해준다.
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(
Arrays.asList(
"http://localhost:3000",
"http://synergyoverflow.s3-website.ap-northeast-2.amazonaws.com"
)
);
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PATCH", "DELETE"));
configuration.setAllowCredentials(true);
configuration.setMaxAge(1000L);
configuration.setAllowedHeaders(Arrays.asList("Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"));
configuration.setExposedHeaders(Arrays.asList("authorization", "refresh"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
유의 사항
- Filter 인터페이스가 여러개이기 때문에 반드시 javax.servlet의 Filter를 구현해준다.
- "Access-Controll-Allow-Origin" 설정에서 주소에 와일드카드"*" 사용시 계속해서 Cors 에러가 발생할 수있다. 이경우 특정 Url을 명시해 준다.
- Token과 같이 클라이언트에서 response header에 접근해야 하는경우 "Access-Control-Expose-Headers"를 이용하여 해당 필드에 접근이 가능하도록 노출시켜주어야한다.
'Projects > Team project - 스택오버플로우 클론코딩' 카테고리의 다른 글
Oauth2 진행 이후 redirect 페이지에서 특정 정보에 접근하기 (0) | 2023.06.21 |
---|---|
팀 프로젝트 일지 (0) | 2023.06.14 |