Enable CORS for API Gateway in AWS CDK

avatar

Borislav Hadzhiev

Sat Apr 24 20213 min read

Updated on Sat Apr 24 2021

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:

lib/cdk-starter-stack.ts
import * as apigateway from '@aws-cdk/aws-apigateway'; import * as cdk from '@aws-cdk/core'; 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, }, });

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 APIs 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:

shell
npx 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:

shell
npx cdk destroy

Further Reading #

Add me on LinkedIn

I'm a Web Developer with TypeScript, React.js, Node.js and AWS experience.

Let's connect on LinkedIn

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee