OPTIONS
사용법
OPTIONS 요청은 대상 리소스에 어떤 동작도 수행하지 않고 그 리소스의 허용 메서드와 기능을 가져옵니다. 서버는 지원되는 메서드를 나열한 Allow 헤더로 응답합니다.
요청 대상으로 별표(*)를 사용하면 그 요청은 특정 리소스가 아니라 서버 전체에 적용됩니다.
OPTIONS * HTTP/1.1
Host: api.example.re
CORS 프리플라이트
실무에서 OPTIONS가 가장 흔히 쓰이는 곳은 CORS 프리플라이트 요청입니다. CORS 안전 목록 밖의 메서드, 커스텀 헤더, 또는 안전 목록(application/x-www-form-urlencoded, multipart/form-data, text/plain) 밖의 Content-Type을 사용하는 교차 출처 요청을 보내기 전에, 브라우저는 대상 서버로 OPTIONS 요청을 자동으로 보냅니다. 프리플라이트는 서버가 실제 요청을 허용하는지 확인합니다.
프리플라이트 요청에는 Origin, Access-Control-Request-Method, 그리고 선택적으로 Access-Control-Request-Headers가 포함됩니다. 서버는 승인을 알리기 위해 Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers로 응답합니다.
리소스 기능 조회
클라이언트가 특정 리소스의 허용 메서드를 조회합니다. 서버는 204 No Content와 Allow 헤더로 응답합니다.
요청
OPTIONS /articles HTTP/1.1
Host: api.example.re
응답
HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD, POST, DELETE
서버 전체 조회
대상으로 *를 사용하면 특정 리소스와 무관하게 서버가 전반적으로 지원하는 메서드를 알 수 있습니다.
요청
OPTIONS * HTTP/1.1
Host: api.example.re
응답
HTTP/1.1 204 No Content
Allow: OPTIONS, GET, HEAD
CORS 프리플라이트
브라우저가 커스텀 X-Request-ID 헤더를 담은 교차 출처 PUT 요청을 준비합니다. 실제 요청을 보내기 전에, 브라우저는 요청 출처에서 그 메서드와 헤더를 서버가 허용하는지 확인하기 위해 프리플라이트 OPTIONS 요청을 보냅니다.
프리플라이트 요청
OPTIONS /api/data HTTP/1.1
Host: api.example.re
Origin: https://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Request-ID
프리플라이트 응답
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Request-ID
Access-Control-Max-Age: 86400
Access-Control-Max-Age 값은 브라우저에게 프리플라이트 결과를 86,400초(하루) 동안 캐시하라고 알려, 같은 엔드포인트에 대한 프리플라이트 요청의 반복을 막아 줍니다.
보안
OPTIONS 응답에는 해당 리소스가 지원하는 모든 메서드를 나열한 Allow 헤더가 포함됩니다. 이는 사소한 정보 노출이며, 보안 스캐너는 활성화된 OPTIONS 엔드포인트를 종종 지적 사항으로 표시합니다. CORS 프리플라이트 요청이 동작하려면 OPTIONS가 필요하므로, OPTIONS를 아예 비활성화하는 것은 실용적인 해법이 아닙니다.
권장되는 접근은 Allow 헤더를 각 엔드포인트에 필요한 메서드로만 제한하는 것입니다. GET과 POST만 받아들이는 리소스가 Allow 목록에 DELETE나 PUT을 광고해서는 안 됩니다.
일부 프레임워크는 POST 요청을 통해 PUT, PATCH, DELETE를 터널링하는 X-HTTP-Method-Override 헤더를 지원합니다. 이는 메서드 기반 접근 제어를 우회하므로, 이 기능을 명시적으로 활성화하고 감사하지 않는다면 보안상 문제가 됩니다.
불필요한 프리플라이트 요청을 피하려면 교차 출처 요청을 “단순” 요청 기준 안에 두세요. 안전 목록 헤더와 안전 목록 콘텐츠 타입만 사용하는 GET, HEAD, POST가 그에 해당합니다. Content-Type: application/json을 쓰면 언제나 프리플라이트가 발생합니다. Access-Control-Max-Age는 프리플라이트 결과를 캐시하여 OPTIONS 왕복의 반복을 줄여 줍니다.