[cocktail-life] OPTIONS 메서드란 (feat. preflight 최적화)

쏘소·2022년 12월 16일
0

프로젝트

목록 보기
18/18
post-custom-banner

요청 메서드 OPTIONS 에 대하여

네트워크 탭을 보니 다음과 같은 popular.php 파일을 요청 방식 OPTIONS 로 불러오고 있었다. 분명 나는 GET 을 통해 서버로 요청해야하는 게 맞는데 왜 OPTIONS 가 있는 것일까?

preflight라고도 불리는 OPTIONS 요청은 브라우저가 서버에게 지원하는 옵션들을 미리 요청하고 허가된 요청에 한해서 전송하기 위한 보안상의 목적이 있다.

발생 이유는 CORS(Cross-Origin Resource Sharing) 와 관련이 있다.
보통 웹서버와 분리되어 있는 API 서버로 요청을 보내거나, 아래처럼 CDN의 이미지를 사용할 때 CORS 가 적용이 되는데, 이는 보안상의 문제점을 가지고 있다. 웹사이트에서 악의적인 목적으로 외부로 정보를 보내거나 하는 등의 요청을 보낼 수 있기 때문이다.

그렇기 때문에 브라우저는 OPTIONS를 preflight하여 서버에서 허용하는 옵션(POST, GET, PUT, DELETE 등)을 미리 확인하고,

허용되지 않은 요청의 경우 405(Method Not Allowed)에러를 발생시키고 실제 요청은 전송하지 않는다.

하지만, OPTION 요청이 항상 발생하는 것은 아닌데,

  1. GET, HEAD, POST 요청 중 하나
  2. user agent에 의해 자동으로 설정되는(Connection, User-Agent, Fetch 스펙상 forbidden header로 정의되어 있는) 헤더외에 CORS-safelisted request-header로 명시된 헤더들만 포함된 경우(Accept, Accept-Language, Content-Language, Content-Type 등)
  3. Content-Type은 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용

이 중 하나라도 만족하지 못한다면 preflight를 날리게 된다.

내 프로젝트를 보면, Content-Type이 application/json으로 3번을 충족하지 못하므로 preflight를 날리게 되는 것이다.

preflight 요청을 줄이면 렌더링 최적화가 가능하지 않을까?

공부하면서 생긴 궁금증으로 preflight를 날리고 받는 것이 렌더링에 영향을 미치지 않을까? 이를 통해 최적화가 가능하지 않을까? 하고 찾아보니 preflight 시간을 줄임으로써 렌더링 최적화하는 방법에 대한 포스트가 있었다.

포스트에 따르면, 대부분의 경우 preflight 응답 시간에 상당한 지연을 초래하여 웹 애플리케이션의 성능에 영향을 미친다고 한다.
따라서, 프리플라이트 요청을 우회하거나 응답 시간을 줄여 웹 애플리케이션의 성능을 향상시킬 수가 있다.

간단하게 방법을 정리해보면,

1. 브라우저를 사용한 preflight 캐싱

브라우저의 캐시를 이용하는 방법이다.

브라우저가 preflight 요청을 보낼 때, 먼저 preflight 캐시에 해당 요청에 대한 응답이 있는지 확인한다. 브라우저가 응답을 찾으면 서버에 preflight 요청을 보내지 않고 캐시된 응답을 사용한다. Preflight 캐시에 응답이 없을 경우에만 브라우저는 preflight 요청을 보내게 된다.

2. 프록시, 게이트웨이 또는 로드 밸런서를 사용한 서버 측 캐싱

프록시, 게이트웨이 또는 AWS CloudFront와 같은 CDN의 기본 캐싱 메커니즘을 사용하여 preflight 요청의 대기 시간을 줄이는 방법이다.

즉, preflight 요청이 이동하는 거리를 줄여서 preflight 요청 응답 시간을 줄이는 방법에 해당한다.

3. 프록시, 게이트웨이 또는 로드 밸런서를 사용하여 preflight 회피하기

프론트엔드와 백엔드를 동일한 도메인을 통해 제공할 수 있다면, CORS가 필요하지 않으므로 preflight 요청을 회피할 수 있다.

프론트엔드에서 간단한 프록시 구성을 사용하여 프론트엔드와 백엔드를 매핑함으로써 이를 쉽게 피할 수 있다.

프로덕션 환경에서는 NGINX, Traefik, AWS CloudFront, AWS Application Load Balancer, Azure Application Gateway와 같은 API 게이트웨이, 로드 밸런서, 프록시 또는 CDN을 사용하여 라우트 기반 구성을 수행할 수 있다고 한다.

4. 간단한 요청(Simple Requests) 사용하기

위에서 언급한 OPTION 요청이 발생하는 조건을 제외한 간단한 요청을 보내는 방법이다.




참고 자료
https://blog.bitsrc.io/4-ways-to-reduce-cors-preflight-time-in-web-apps-1f47fe7558
https://nukeguys.github.io/dev/options-request/

profile
개발하면서 행복하기
post-custom-banner

0개의 댓글