

# API Gateway의 REST API CORS
<a name="how-to-cors"></a>

[CORS(Cross-origin 리소스 공유)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)는 브라우저에서 실행 중인 스크립트에서 시작되는 cross-origin HTTP 요청을 제한하는 브라우저 보안 기능입니다. 자세한 내용은 [CORS란 무엇인가요?](https://aws.amazon.com/what-is/cross-origin-resource-sharing/)를 참조하세요.

## CORS 지원 활성화 여부 확인
<a name="apigateway-cors-request-types"></a>

*cross-origin* HTTP 요청은 다음에 대해 이루어지는 요청입니다.
+ 다른 *도메인*(예: `example.com`에서 `amazondomains.com`으로)
+ 다른 *하위 도메인*(예: `example.com`에서 `petstore.example.com`으로)
+ 다른 *포트*(예: `example.com`에서 `example.com:10777`으로)
+ 다른 *프로토콜*(예: `https://example.com`에서 `http://example.com`으로)

 API에 액세스할 수 없고 `Cross-Origin Request Blocked`가 포함된 오류 메시지를 수신하는 경우 CORS를 활성화해야 할 수 있습니다.

Cross-origin HTTP 요청은 *단순* 요청과 *비 단순* 요청의 두 가지 유형으로 나눌 수 있습니다.

## 단순한 요청을 위한 CORS 사용 설정
<a name="apigateway-cors-simple-request"></a>

다음과 같은 모든 조건을 충족하는 HTTP 요청은 *단순* 요청입니다.
+ `GET`, `HEAD`, `POST` 요청만 허용하는 API 리소스에 대해 발행된 요청입니다.
+ `POST` 메서드 요청인 경우 `Origin` 헤더를 포함해야 합니다.
+ 요청 페이로드 콘텐츠 유형이 `text/plain`, `multipart/form-data` 또는 `application/x-www-form-urlencoded`입니다.
+ 요청에 사용자 지정 헤더가 없습니다.
+ [단순 요청에 대한 Mozilla CORS 문서](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests)에 나열된 추가 요청.

간단한 교차 오리진 `POST` 메서드 요청의 경우 리소스의 응답에 `Access-Control-Allow-Origin: '*'` 또는 `Access-Control-Allow-Origin:'origin'` 헤더가 포함되어야 합니다.

다른 모든 cross-origin HTTP 요청은 *비 단순* 요청입니다.

## 단순하지 않은 요청을 위한 CORS 사용 설정
<a name="apigateway-enable-cors-non-simple"></a>

API 리소스가 단순하지 않은 요청을 받는 경우 통합 유형에 따라 추가 CORS 지원을 사용 설정해야 합니다.

### 비프록시 통합을 위한 CORS 사용 설정
<a name="apigateway-enable-cors-mock"></a>

이러한 통합의 경우 [CORS 프로토콜](https://fetch.spec.whatwg.org/#http-cors-protocol)은 브라우저에 사전 요청을 서버로 보내고, 서버 승인(또는 보안 인증 정보 요청)을 기다린 후 실제 요청을 보내도록 요구합니다. 사전 요청에 적절한 응답을 보내도록 API를 구성해야 합니다.

 사전 요청에 대한 응답을 만드는 방법 

1. 임의 통합으로 `OPTIONS` 메서드를 생성합니다.

1. 다음 응답 헤더를 200 메서드 응답에 추가합니다.
   + `Access-Control-Allow-Headers`
   + `Access-Control-Allow-Methods`
   + `Access-Control-Allow-Origin`

1. 통합 패스스루 동작을 `NEVER`로 설정합니다. 이 경우 매핑되지 않은 콘텐츠 유형의 메서드 요청은 HTTP 415 미지원 미디어 유형 응답과 함께 거부됩니다. 자세한 내용은 [API Gateway의 REST API에 대한 매핑 템플릿이 없는 페이로드의 메서드 요청 동작](integration-passthrough-behaviors.md) 섹션을 참조하세요.

1. 응답 헤더의 값을 입력합니다. 모든 오리진, 모든 메서드 및 일반적인 헤더를 허용하려면 다음 헤더 값을 사용합니다.
   + `Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'`
   + `Access-Control-Allow-Methods: 'DELETE,GET,HEAD,OPTIONS,PUT,POST,PATCH'`
   + `Access-Control-Allow-Origin: '*'`

사전 요청을 생성한 후에는 CORS 사용이 설정된 모든 메서드에서 최소 200개 응답 모두에 대해 `Access-Control-Allow-Origin: '*'` 또는 `Access-Control-Allow-Origin:'origin'` 헤더를 반환해야 합니다.

### AWS Management Console을 사용하여 비프록시 통합을 위한 CORS 사용 설정
<a name="apigateway-enable-cors-mock-console"></a>

AWS Management Console을 사용하여 CORS를 활성화할 수 있습니다. API Gateway에서 `OPTIONS` 메서드를 생성하고 기존 메서드 통합 응답에 `Access-Control-Allow-Origin` 헤더를 추가합니다. 이 방법이 항상 효과가 있는 것은 아니며, CORS 사용이 설정된 모든 메서드에서 최소 200개 응답 모두에 대해 `Access-Control-Allow-Origin` 헤더를 반환하도록 통합 응답을 수동으로 수정해야 하는 경우도 있습니다.

API에 대해 바이너리 미디어 유형이 `*/*`로 설정된 경우 API Gateway가 `OPTIONS` 메서드를 생성할 때 `contentHandling`을 `CONVERT_TO_TEXT`로 변경합니다.

다음 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration.html) 명령은 통합 요청에 대해 `contentHandling`을 `CONVERT_TO_TEXT`로 변경합니다.

```
aws apigateway update-integration \
  --rest-api-id abc123 \
  --resource-id aaa111 \
  --http-method OPTIONS \
  --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
```

다음 [update-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration-response.html) 명령은 통합 응답에 대해 `contentHandling`을 `CONVERT_TO_TEXT`로 변경합니다.

```
aws apigateway update-integration-response \
  --rest-api-id abc123 \
  --resource-id aaa111 \
  --http-method OPTIONS \
  --status-code 200 \
  --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
```

## 프록시 통합을 위한 CORS 지원 사용 설정
<a name="apigateway-enable-cors-proxy"></a>

Lambda 프록시 통합 또는 HTTP 프록시 통합의 경우 프록시 통합은 통합 응답을 반환하지 않기 때문에 `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods`, `Access-Control-Allow-Headers` 헤더를 반환할 책임이 백엔드에 있습니다.

다음 예제 Lambda 함수는 필요한 CORS 헤더를 반환합니다.

------
#### [ Node.js ]

```
export const handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Headers" : "Content-Type",
            "Access-Control-Allow-Origin": "https://www.example.com",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
        },
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

------
#### [ Python 3 ]

```
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Allow-Origin': 'https://www.example.com',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        },
        'body': json.dumps('Hello from Lambda!')
    }
```

------

**Topics**
+ [CORS 지원 활성화 여부 확인](#apigateway-cors-request-types)
+ [단순한 요청을 위한 CORS 사용 설정](#apigateway-cors-simple-request)
+ [단순하지 않은 요청을 위한 CORS 사용 설정](#apigateway-enable-cors-non-simple)
+ [프록시 통합을 위한 CORS 지원 사용 설정](#apigateway-enable-cors-proxy)
+ [API Gateway 콘솔을 사용하여 리소스에서 CORS 활성화](how-to-cors-console.md)
+ [API Gateway 가져오기 API를 사용하여 리소스에서 CORS 활성화](enable-cors-for-resource-using-swagger-importer-tool.md)
+ [API Gateway API용 CORS 테스트](apigateway-test-cors.md)