Enable CORS for API Gateway in AWS CDK


Borislav Hadzhiev

Last updated: Apr 13, 2022


Check out my new book

Enable CORS for API Gateway in AWS CDK #

CORS is a mechanism that allows a server to use a combination of HTTP headers to indicate from which domains, other than its own, it receives requests.

By default servers only take requests made from applications hosted on the same domain.

Setting CORS configuration is important when we access resources from a different domain.

The API Gateway service hosts APIs on the https://amazonaws.com domain, which is different from where we host our client applications, so we have to enable CORS.

The code for this article is available on GitHub

In order to demo how to set up CORS for API Gateway, I'll create a simple CDK app that consist of a single Rest API:

import * as apigateway from 'aws-cdk-lib/aws-apigateway'; import * as cdk from 'aws-cdk-lib'; export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const restApi = new apigateway.RestApi(this, 'api', { description: 'example-api', // 👇 set up CORS defaultCorsPreflightOptions: { allowHeaders: [ 'Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key', ], allowMethods: ['OPTIONS', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'], allowCredentials: true, allowOrigins: ['http://localhost:3000'], }, }); // 👇 add a resource with 2 methods for demo purposes const todos = restApi.root.addResource('todos'); todos.addMethod('GET'); todos.addMethod('POST'); } } const app = new cdk.App(); new MyCdkStack(app, 'my-cdk-stack', { stackName: 'my-cdk-stack', env: { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT, }, });
If you still use CDK version 1, switch to the cdk-v1 branch in the GitHub repository.

In the code snippet we have:

  1. Used the Rest API construct to create an API Gateway
  2. We've passed the defaultCorsPreflightOptions prop to set up CORS for all of the API's routes
  3. We've added a todos resource with GET and POST methods, just to see that the CORS configuration will apply to both.

The configuration parameters we've used for CORS are:

  • allowedHeaders - specifies which HTTP headers the frontend is allowed to use when making request to our REST Api
  • allowMethods - an array of the HTTP methods our frontend is allowed to use when calling our REST Api
  • allowCredentials - whether to expose the API Gateway response to the frontend when the request's credentials mode is set to include. When credentials mode is set to include, our frontend will always send user credentials (i.e. cookies, auth headers) even for CORS calls.
  • allowOrigins - an array of the origins that are allowed to make requests to our rest API. If you own a domain https://example.com that's what you'd set here.

Now I'll deploy the stack:

npx aws-cdk deploy

At this point if we open the CloudFormation console, we can see that our API has been deployed:

cloudformation deployed

If we now open the OPTIONS endpoint for any of the routes, we can see that the CORS headers are applied at the Integration Response stage:

cors headers applied

If we want a more fine grained approach to setting cors, we can do it on a per-resource basis, i.e.:

const todos = restApi.root.addResource('todos'); todos.addMethod('GET'); todos.addMethod('POST'); todos.addCorsPreflight({ allowHeaders: ['Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key'], allowMethods: ['OPTIONS', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'], allowCredentials: true, allowOrigins: ['http://localhost:3000'], });

However, setting CORS globally has been more common in my experience, so the defaultCorsPreflightOptions prop is what you'll want to use most of the time.

Troubleshooting CORS of API Gateway in AWS CDK #

Note that we often get cors errors when making HTTP requests to APIs, when we type in the endpoint or the HTTP method wrong.

For instance, if I make a POST request to https://api-id.aws.amazon.com/wrong-path I'll get a CORS error in the console of my browser.

The same happens if I send a request with an HTTP method that the endpoint does not support, I'll still get a CORS error.

Clean up #

To delete the stack and the provisioned resources we can run the cdk destroy command:

npx aws-cdk destroy

Further Reading #

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.