CORS(Cross-Origin Resource Sharing)란? Spring Tomcat 설정과 함께 간략히!
🙆♂️ import 🙇♂️
CORS
CORS(Cross-Origin Resource Sharing)란 추가 HTTP Header를 사용하여,
한 출처에서 실행 중인 Web Application이 다른 출처의 선택한 Resource에 접근할 수 있는 권한을 부여하도록 Browser에 알려주는 체제이다.
Web Application은 Resource가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 Cross-Origin HTTP Request를 실행한다.
기본적으로 Browser는 보안상의 이유로,
Srcipt단에서 Cross-Origin HTTP Request를 제한한다.
https://ddaja.com (Front-End Server) -> XMLHttpRequest(JS) -> https://api.ddaja.com/resources (X)
XMLHttpRequest와 Fetch API는 동일 출처 정책을 기본 정책으로 수행한다.
동일 출처 정책 : 자신의 출처(Web Application)와 동일한 Resource만 불러 올 수 있음.
만약 다른 출처의 Resource를 불러오려면 다른 출처 측에서 올바른 CORS Header를 포함한 Response를 반환해야 한다.

CORS 공유 표준
Origin Header
CORS 공유 표준은 해당 Resource에 접근하는 것이 허용된 출처를 새로운 HTTP Header를 통해 제공하여 공유한다.
Request(https://ddaja.com)
GET https://api.ddaja.com/resources/1 HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
// 출처 제공
Origin: https://ddaja.com
Response(https://api.ddaja.com)
HTTP/1.1 200 OK
Date: Mon, 14 07 2021 00:23:53 KST
Server: Apache/2
// 응답 제공하는 서버 측에 설정된 Allow-Origin에 포함되면 공유 가능
Access-Control-Allow-Origin: https://ddaja.com, https://haja.com
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
Preflight - Options method
CORS 명세 중 Preflight하여 실제 Request 전송 전에 먼저 허용 가능한지 Request를 전송 하여 Resource를 공유하는 명세가 있다.
요청을 받는 다른 출처의 WebApplication 측에서,
Resource에 대해 Side Effect가 발생할 수 있는 HTTP Request Method(POST, PUT, PATCH, DELETE)에 대한 요청에 대해,
요청 하는 Browser에서 다른 출처의 WebApplication에 OPTIONS Method로,
Preflight하여 허용 가능한 Method 목록을 먼저 요청한 후,
접근 허가가 떨어지면 실제 Resource에 대한 Request를 보내도록 요구한다.
이때 다른 출처 Web Application 측에서 인증 정보(Cookie, SessionID, …)를 함께 전송해야 한다고 명세할 수도 있다.

위 사진은 다음과 같은 과정으로 이루어진다.
-
Client는 먼저 실제 Request인POSTMethod를Access-Control-Request-MethodHeader에 설정,OPTIONSMethod로 먼저 Preflight하여 허용 가능한지 Server에 점검 받는다. -
Server는Client의Origin이 자신이 설정한Access-Control-Allow-Origin에 포함되었는지,Access-Control-Request-Method가 자신이 허용한Acess-Control-Allow-Methods에 포함되었는지,Access-Control-Request-Headers가 자신이 설정한Access-Control-Allow-Header에 포함되었는지 확인하여, 결과를Client에 전송한다. -
Server로 부터200 OKResponse를 받은Client는 원래 요청하길 원했던POSTMethod로 Request를 전송하여 최종 Resource를 응답받는다.
In Java With Tomcat Server
만약 Java Web Application에서 Tomcat Server로 CORS 설정을 하고 싶다면,
아래와 같이 Tomcat의 web.xml에 filter설정을 해둔 후,
Filter를 implements하는 CORSFilter Class를 아래와 같은 예시로 선언하면 된다.
<filter>
<filter-name>cors</filter-name>
<filter-class>project.config.filter.SimpleCORSFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
public class SimpleCORSFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 허용할 Method 목록
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
httpResponse.setHeader("Access-Control-Max-Age", "3600");
// 허용할 Header 목록
httpResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with, content-type, Authorization");
// 허용할 다른 출처 도메인 목록
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) {
// Do nothing
}
@Override
public void destroy() {
// Do nothing
}
}
위 web.xml 설정과, SimpleCORSFilter.Class는 해당 서버의 모든 URL을 Filter하여,
Response의 Header에 설정한 CORS Header 정보를 삽입해 준다.
댓글남기기