오늘 배울 것은 CORS다 먼저 Cors가 무엇일까 >?
한줄 요약을 해주자면! cors == 브라우저 보안정책 이라고 보면된다
끝!!! .... 이 아니라 자세히 알아보자.
먼저 콘솔 에러창에 수많은 에러가 뜰수 있다 그중에서 Access...Control-Allow-Origin...with CORS disabled. 이런 에러가 뜬다면 cors 설정을 해줘야 한다. 설정을 변경하기전에
왜 이런 에러가 뜰까 ??
CORS 에러는 브라우저에서 서로 다른 도메인/포트의 서버로 요청이 갈때 브라우저에서 발생한다.
.해결 방법으로
- 미들웨어 설치 & 설정 (프론트엔드/백엔드 둘다 해당)
- 프록시방식 사용 : 브라우저에서 프론트서버로 요청 > 프론트서버에서 백엔드서버로 요청.
프론트에서 요청 header에 Access-Control-Allow-Origin:'도메인:포트 or *(모든도메인)' 옵션 사용이 있다.
총 정리해서 다시 설명해 주자면
프론트의 도메인이 localhost: 8000이며 백엔드의 도메인은 localhost: 9000일 경우에
1. 프론트 엔드에서는 백엔드로 api 를 보냄
2. 백엔드에서는 프론트와 백엔드의 도메인이 달라진 것을 감지함.
3. cors가 허용하는 여부에 따라서 프론트엔드가 요청한 것을 허용 또는 거부함
스프링 부트로 cors를 해결하는 방법은 무엇일까 ?
이런 Preflight 상황에서 적절한 Access-Control 을 위한 해결 방법이 3가지가 존재한다.
- CorsFilter 로 직접 response에 header 를 넣어주기
- Controller 에서 @CrossOrigin 어노테이션 추가하기
- WebMvcConfigurer 를 이용해서 처리하기
CorsFilter 생성하기
첫 번째로 알아볼 방법은 커스텀 필터를 만드는 것이다.
Access-Control 을 확인할 수 있도록 커스텀 Filter 를 생성해보자.
필자는 이러한 구조인데, 아무 위치에서도 좋으니 filter 라는 디렉토리를 생성한다.
그리고 해당 디렉토리 아래에 CorsFilter 라는 클래스를 하나 생성해보도록 하자.
그리고 해당 클래스를 Bean 으로 등록하기 위해서 프레임워크에게 알려야 한다.
@Component 이라는 어노테이션을 추가하고, Filter 인터페이스를 구현하여 Override 해보자.
주의해야할 것이 있는데, Filter 는 꼭 javax.servlet 의 Filter를 사용해야 한다.
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
우리는 해당 필터가 실제로 수행할 doFilter 를 커스텀해야 한다.
다음과 같이 작성해보자.
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements 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", "3600");
response.setHeader("Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization");
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
}else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
}
우리가 필요한 헤더를 OPTIONS 가 잘 확인할 수 있도록 설정해줄 수 있다.
CrossOrigin 어노테이션 사용하기
CrossOrigin 어노테이션을 사용하는 방법은 매우 간단하다.
컨트롤러에서 특정 메서드 혹은 컨트롤러 상단부에 @CrossOrigin 만 추가하면 된다.
@RestController
@RequestMapping(value = "/api/threats", produces = "application/json")
@CrossOrigin(origins = "http://front-server.com") // 컨트롤러에서 설정
public class ThreatController {
private final ThreatService threatService;
public ThreatController(ThreatService threatService) {
this.threatService = threatService;
}
@GetMapping
@CrossOrigin(origins = "http://front-server.com") // 메서드에서 설정
public ResponseEntity<ThreatLogCountResponse> getAllThreatLogs() {
return ResponseEntity.ok(threatService.getAllThreatLogCount());
}
}
설정 방법은 2가지가 있는데,
- 컨트롤러 클래스 단에서 설정
- 메서드 단에서 설정
둘중 하나의 방법만 사용해도 된다.
하지만 단점이라고 한다면 컨트롤러가 많을 수록 설정해야하는 어노테이션이 많아진다는 것이다.
WebMvcConfigurer 에서 설정하기
해당 사용법도 간단하다.
Spring Initializer 를 이용해서 프로젝트를 만들었다면 다음과 같은 main 함수가 존재한다.
@SpringBootApplication
public class RestServiceCorsApplication {
public static void main(String[] args) {
SpringApplication.run(RestServiceCorsApplication.class, args);
}
}
해당 main 함수에서 Bean 으로 Configurer 를 추가해주면 된다.
@SpringBootApplication
public class RestServiceCorsApplication {
public static void main(String[] args) {
SpringApplication.run(RestServiceCorsApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://front-server.com");
}
};
}
}
물론 이 방법은 @Configuration 을 허용한 클래스에서 등록을 할 수도 있다.
참고 블로그 : https://wonit.tistory.com/572
'이노베이션 캠프 WIL' 카테고리의 다른 글
7주차 WIL( 클론코딩 ) (0) | 2022.08.07 |
---|---|
6 주차 WIL (미니프로젝트, 협업 ) (0) | 2022.07.31 |
4주차 WIL(ORM, SQL, MVC) (0) | 2022.07.17 |
3주차 WlL(DI, IoC, Bean) (0) | 2022.07.10 |
2주차 WIL (객체 지향 프로그래밍 , JVM) (0) | 2022.07.03 |
댓글