Use API Gateway with Mock integration to allow CORS from multiple Origins

Srikanth Sharma
4 min readAug 22, 2020

--

Many would have faced the problem of CORS at one point in their AWS journey, when creating APIs using API Gateway. I too had been there several times. I feel that in many organisations, the power of API Gateway is very under-used, under-evaluated and under-appreciated. My learnings about this was confined even after watching several paid and free video contents offered by various learning platforms. I tried to read and comprehend AWS documentation but only after multiple discontinuous attempts over a period of few months, I am now able to understand some basics. Hence, I wanted to capture my learning of enabling CORS using Mock Integration, here.

API Gateway Integration Options

API Gateway offers various integrations and most of us would have wondered about the use of Mock integration other than that for testing purpose. One such use case is for resolving CORS issues.

Problem statement

When an API is requested from an origin different from where it is hosted, due to security reasons, CORS error occurs which prevents that API call unless it is allowed using Access-Control-Allow-Origin header. So, before a POST call, a pre-flight is triggered which is OPTIONS with headers like Access-Control-Allow-Headers and Access-Control-Allow-Methods. It also has a header called Origin which could be like https://www.example.com or http://localhost:3000 if you are running it from a development server.

Solution Overview

Based on our requirements, we have two cases here.

  1. If the origin is fixed or if all origins need to be allowed using wildcard like *
  2. If we need to allow all origins from a list.

In either case, common steps are:

Click on Create Method and choose OPTIONS.

API Gateway method execution screen

Case-1:

We can directly go to Integration Response and by defaultAccess-Control-Allow-Origin is set to'*'. We can change this value to 'https://www.example.com' if in case we are accessing it from that particular origin.

Case-2:

But in this case we select Method Request and add origin as required header.

Origin as mandatory header in method execution

Choose Mock integration from Integration Request (as shown in first diagram depicting various integration options). Then we need to define the logic in Mapping Templates. This requires understanding of Velocity Template Language. Since I was in a learning phase, I was looking for some logic in VTL to help me out. Thanks to Dhiraj Agarwal, I got a solution from stackoverflow.com.

The above logic has an Array of origins under $domains and we fetch the current origin from $input.params("origin"). Finally if the value matches any one of the origin in Array, the Access-Control-Allow-Origin is overridden in line 10.

Testing

I am not saying that the latency will be 3ms in real-life scenario. Since it is tested within API Gateway it is very low. All I am saying is if we integrate this with a Lambda function, some minimal additional latency will be added.

Test Result

(Note: Here I am using www.example.com without http:// after making changes in code because this testing IDE does not support additional :. But if you test from postman or insomnia, it works as expected.)

In case a fallback domain is required, either we can make the logic change in Integration using VTL or specify it in Integration Response as shown below. When the value is not found, this one will be used.

Fallback in Integration Response

Summary

The advantages of this solution are:

  • it will have very low latency as the payload is not passed to other AWS services like lambda which can take some time to load and execute.
  • Invoking lambda function will cost us for every 100ms but this logic is handled by API gateway without any additional charges.

Stay tuned for more cost effective solutions on AWS. Special thanks to Dipti Kumari for helping me proofread.

--

--