Spring CORS 에러 해결
Spring CORS 에러 해결 방법
- 개요 : node axios를 통해서 클라이언트와 통신하던 중 CORS 문제와 마주쳤다. 이를 해결하기위해 서칭하던 중 적어둘 필요가 있어서 적어둔다.
1. CORS(Cross-Origin Resource Sharing) policy란?
- CORS 정책을 위반할 때 발생한다.
- 브라우저에서 다른 출처의 리소스를 공유하는 방법에서의 정책을 위반할 시 발생한다.
1-1. 다른 출처의 리소스란?
-
URL 구조
-
출처(Origin)이란?
- 출처란 URL 구조에서 살펴본 Protocol, Host, Port를 합친것을 의미한다.
-
동일 출처 정책(SOP: Same-Origin Policy)란?
- 브라우저에서 API 호출할때만 CORS policy를 만나는 이유는 브라우저가 동일 출처 정책을 지켜서 그렇다.
- SOP란 다른 출처의 리소스 접근을 금지하는 정책이다.
- 예를 들어서
beomy.github.io
라는 도메인 주소를 사용중인 웹페이지에서 beomy-api.github.io
라는 API 서버로 데이터를 요청해 화면을 그리면 해당 웹페이지는 동일 출저 정책(SOP)를 위반한 것이다.
- 현실적으로 외부 리소스를 참고하는것이 필요하기에 외부 리소스를 가져올 수 있는 방법이 존재해야 한다.
- 외부 리소스를 사용하기 위한 SOP 예외 조항이 CORS이다.
1-2. CORS 동작원리
-
simple request
-
단순 요청은 서버에 API를 요청하고, 서버는 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보낸다. 브라우저는 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.
-
simple request 조건 : 서버로 전달하는 요청(request)이 아래의 3가지 조건을 만족해야 서버로 전달하는 요청이 단순 요청으로 동작한다.
- 요청 메서드(method)는 GET, HEAD, POST 중 하나여야 합니다.
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안 됩니다.
- Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나를 사용해야 합니다
- 첫 번째 조건은 어렵지 않은 조건이지만 2번, 3번 조건은 까다로운 조건입니다. 2번 조건은 사용자 인증에 사용되는 Authorization 헤더도 포함되지 않아 까다로운 조건이며, 3번 조건은 많은 REST API들이 Content-Type으로 application/json을 사용하기 때문에 지켜지기 어려운 조건입니다.
-
preflight request
- Preflight 요청은 서버에 예비 요청을 보내서 안전한지 판단한 후 본 요청을 보내는 방법.
- Preflight 요청은 실제 리소스를 요청하기 전에 OPTIONS라는 메서드를 통해 실제 요청을 전송할지 판단한다.
- OPTIONS 메서드로 서버에 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보낸다. 브라우저는 단순 요청과 동일하게 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단한다.
-
CORS 해결 방법
- Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보내는 방식으로 CORS 에러를 해결할 수 있다.
2. Spring CORS 해결 방법
-
CorsFilter 클래스 생성
- filter 패키지를 만들고, CorsFilter 클래스를 생성한다. (패키지 위치는 자유)
-
다음의 코드를 넣는다.
package com.test.blog.filter;
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 {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@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:8090");
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() {
Filter.super.destroy();
}
}
Author And Source
이 문제에 관하여(Spring CORS 에러 해결), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@jiseok/Spring-CORS-에러-해결
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
URL 구조
출처(Origin)이란?
- 출처란 URL 구조에서 살펴본 Protocol, Host, Port를 합친것을 의미한다.
동일 출처 정책(SOP: Same-Origin Policy)란?
- 브라우저에서 API 호출할때만 CORS policy를 만나는 이유는 브라우저가 동일 출처 정책을 지켜서 그렇다.
- SOP란 다른 출처의 리소스 접근을 금지하는 정책이다.
- 예를 들어서
beomy.github.io
라는 도메인 주소를 사용중인 웹페이지에서beomy-api.github.io
라는 API 서버로 데이터를 요청해 화면을 그리면 해당 웹페이지는 동일 출저 정책(SOP)를 위반한 것이다. - 현실적으로 외부 리소스를 참고하는것이 필요하기에 외부 리소스를 가져올 수 있는 방법이 존재해야 한다.
- 외부 리소스를 사용하기 위한 SOP 예외 조항이 CORS이다.
simple request
-
단순 요청은 서버에 API를 요청하고, 서버는 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보낸다. 브라우저는 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단합니다.
-
simple request 조건 : 서버로 전달하는 요청(request)이 아래의 3가지 조건을 만족해야 서버로 전달하는 요청이 단순 요청으로 동작한다.
- 요청 메서드(method)는 GET, HEAD, POST 중 하나여야 합니다.
- Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안 됩니다.
- Content-Type 헤더는 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나를 사용해야 합니다
- 첫 번째 조건은 어렵지 않은 조건이지만 2번, 3번 조건은 까다로운 조건입니다. 2번 조건은 사용자 인증에 사용되는 Authorization 헤더도 포함되지 않아 까다로운 조건이며, 3번 조건은 많은 REST API들이 Content-Type으로 application/json을 사용하기 때문에 지켜지기 어려운 조건입니다.
preflight request
- Preflight 요청은 서버에 예비 요청을 보내서 안전한지 판단한 후 본 요청을 보내는 방법.
- Preflight 요청은 실제 리소스를 요청하기 전에 OPTIONS라는 메서드를 통해 실제 요청을 전송할지 판단한다.
- OPTIONS 메서드로 서버에 예비 요청을 먼저 보내고, 서버는 이 예비 요청에 대한 응답으로 Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보낸다. 브라우저는 단순 요청과 동일하게 Access-Control-Allow-Origin 헤더를 확인해서 CORS 동작을 수행할지 판단한다.
CORS 해결 방법
- Access-Control-Allow-Origin 헤더를 포함한 응답을 브라우저에 보내는 방식으로 CORS 에러를 해결할 수 있다.
CorsFilter 클래스 생성
- filter 패키지를 만들고, CorsFilter 클래스를 생성한다. (패키지 위치는 자유)
다음의 코드를 넣는다.
package com.test.blog.filter;
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 {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@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:8090");
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() {
Filter.super.destroy();
}
}
Author And Source
이 문제에 관하여(Spring CORS 에러 해결), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jiseok/Spring-CORS-에러-해결저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)