Enabling CORS for a REST API resource - Amazon API Gateway

Enabling CORS for a REST API resource

Cross-origin resource sharing (CORS) is a browser security feature that restricts cross-origin HTTP requests that are initiated from scripts running in the browser.

Determining whether to enable CORS support

A cross-origin HTTP request is one that is made to:

  • A different domain (for example, from example.com to amazondomains.com)

  • A different subdomain (for example, from example.com to petstore.example.com)

  • A different port (for example, from example.com to example.com:10777)

  • A different protocol (for example, from https://example.com to http://example.com)

Cross-origin HTTP requests can be divided into two types: simple requests and non-simple requests.

Enabling CORS for a simple request

An HTTP request is simple if all of the following conditions are true:

  • It is issued against an API resource that allows only GET, HEAD, and POST requests.

  • If it is a POST method request, it must include an Origin header.

  • The request payload content type is text/plain, multipart/form-data, or application/x-www-form-urlencoded.

  • The request does not contain custom headers.

  • Any additional requirements that are listed in the Mozilla CORS documentation for simple requests.

For simple cross-origin POST method requests, the response from your resource needs to include the header Access-Control-Allow-Origin: '*' or Access-Control-Allow-Origin:'origin'.

All other cross-origin HTTP requests are non-simple requests.

Enabling CORS for a non-simple request

If your API's resources receive non-simple requests, you must enable additional CORS support depending on your integration type.

Enabling CORS for non-proxy integrations

For these integrations, the CORS protocol requires the browser to send a preflight request to the server and wait for approval (or a request for credentials) from the server before sending the actual request. You must configure your API to send an appropriate response to the preflight request.

To create a preflight response:

  1. Create an OPTIONS method with a mock integration.

  2. Add the following response headers to the 200 method response:

    • Access-Control-Allow-Headers

    • Access-Control-Allow-Methods

    • Access-Control-Allow-Origin

  3. Enter values for the response headers. To allow all origins, all methods, and common headers, use the following header values:

    • Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'

    • Access-Control-Allow-Methods: '*'

    • Access-Control-Allow-Origin: '*'

After creating the preflight request, you must return the Access-Control-Allow-Origin: '*' or Access-Control-Allow-Origin:'origin' header for all CORS-enabled methods for at least all 200 responses.

Enabling CORS for non-proxy integrations using the AWS Management Console

You can use the AWS Management Console to enable CORS. API Gateway creates an OPTIONS method and adds the Access-Control-Allow-Origin header to your existing method integration responses. This doesn’t always work, and sometimes you need to manually modify the integration response to return the Access-Control-Allow-Origin header for all CORS-enabled methods for at least all 200 responses.

Enabling CORS support for proxy integrations

For a Lambda proxy integration or HTTP proxy integration, your backend is responsible for returning the Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers headers, because a proxy integration doesn't return an integration response.

The following example Lambda functions return the required CORS headers:

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!') }