교차 출처 리소스 공유 (CORS)

Seongmin·2023년 1월 15일
0

CS

목록 보기
6/6

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)

추가 HTTP 헤더를 사용하여 한 출처(프로토콜, 도메인, 포트)에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제

웹 애플리케이션은 리소스가 자신의 출처와 다를때 교차 출처 HTTP 요청을 실행한다.

웹 브라우저는 보안 상의 이유로 스크립트에서 실행된 교차 출처 HTTP 요청을 제한한다. XMLHttpRequest와 FetchAPI는 동일 출처 정책을 따르기 때문에 자신의 출처와 동일한 리소스만을 불러올 수 있고, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.

개요

서버는 접근이 허용된 출처에 대한 Http 헤더를 추가한다.

프리플라이트 : 서버에서 어떤 메서드와 어떤 header 를 허용하는지 확인하는 과정

  • CORS는 side effect를 불러오는 POST, UPDATE, DELETE 요청에 대해, 브라우저가 요청을 option 메서드로 프리플라이트 하여 메서드를 요청하고, 서버의 허가가 떨어지면 실제 요청을 보내도록 한다.

접근 제어 시나리오 예제

XMLHttpRequest를 사용한 예제들

1. 단순 요청

조건

CORS preflight를 트리거하지 않는 요청으로, 다음 조건을 모두 충족해야 한다.

  • 다음 중 하나의 메서드
    • GET
    • HEAD
    • POST

  • 수동으로 설정할 수 있는 헤더는 오직 Fetch 명세에서 “CORS-safelisted request-header”로 정의한 헤더 뿐
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type

  • Content-Type 헤더는 다음의 값들만 허용
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

  • 요청에 사용된 XMLHttpRequestUpload 객체에는 이벤트 리스너가 등록되어 있지 않습니다. 이들은 XMLHttpRequest.upload 프로퍼티를 사용하여 접근합니다.

  • 요청에 ReadableStream 객체가 사용되지 않습니다.

2. 프리플라이트 요청

먼저 OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인

3. 인증정보를 포함한 요청

HTTP cookies와 HTTP Autehntication 정보를 인식하여 브라우저에서 자격 증명을 보냈는지 확인한다. 때문에 XMLHttpRequest 객체나 Request 생성자가 호출될 때 withCredentials와 같은 플래그를 설정해야 한다.

const invocation = new XMLHttpRequest();
const url = 'http://bar.other/resources/credentialed-content/';

function callOtherDomain() {
  if (invocation) {
    invocation.open('GET', url, true);
    invocation.withCredentials = true;
    invocation.onreadystatechange = handler;
    invocation.send();
  }
}

브라우저는 Access-Control-Allow-Credentials: true 헤더가 없는 응답을 거부한다.

The most important headers in CORS

  • Access-Control-Allow-Origin
    • This header specifies which domains are allowed to access the resources on the server. The value of this header can be a specific domain (e.g. "http://example.com"), or "*" to allow any domain to access the resources.
  • Access-Control-Allow-Methods
    • This header specifies which HTTP methods are allowed for CORS requests.
  • Access-Control-Allow-Headers
    • This header specifies which request headers are allowed for CORS requests.
  • Access-Control-Allow-Credentials
    • This header specifies whether or not the response to the request can be exposed when the credentials flag is true.
import java.io.IOException;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException {
        response.setHeader("Access-Control-Allow-Origin", "http://example.com");
        response.setHeader("Access-Control-Allow-Methods", "GET");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        // ... other code to handle the request and generate the response
    }
}

출처


https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

더 읽을거리


0개의 댓글