Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API Gateway CORS Issue

So I have CORS enabled going through the basic setup given by AWS Gateway. However for this API I need to allow Control Origins for all requests and allow credentials.

Here is what it looks like

enter image description here

The issue as you may have guessed is this setup is not allowed by CORS, you can not have a wildcard for Origin and have credentials as true. Normally the work around for this is to just grab the requesting domain and add it into the Origin Header. Which is more or less what I want to do. But I don't know how to get that information and add it as a mapping value. Where does API Gateway store that information and how do i get it?

UPDATE: I have to pass through HTTP Header Host to my Lambda Function which I should have mentioned earlier, I have tried implementing the Answer below but I cannot access the header to pass it to the Lambda function using the instructions provided. Any more assistance with this is greatly appreciated.

like image 550
wmfrancia Avatar asked Feb 08 '16 19:02

wmfrancia


People also ask

How do I test a CORS API gateway?

You can test your API's CORS configuration by invoking your API, and checking the CORS headers in the response. The following curl command sends an OPTIONS request to a deployed API.

How do you fix CORS missing Allow origin?

If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.

How do I fix local CORS error?

Use the proxy setting in Create React App"proxy": "https://cat-fact.herokuapp.com/", Now when you make an API request to https://localhost:3000/api/facts Create React App will proxy the API request to https://cat-fact.herokuapp.com/facts and the CORS error will be resolved.


1 Answers

Okay After hours of research and finding bits of information across the internet I have a solution and hopefully it is useful for other people.

To pass an HTTP Header that is not a default value provided by AWS API Gateway and then access that data via a Lambda Function and return that data in the Response Header follow the steps below

  1. In "Method Request" go to "HTTP Request Headers" and add your desired header to capture. ie. if we want to get the host value of the API url you can enter "Host" here. if you want to get the website host of the caller use "Origin"

  2. In "Integration Request" go to mapping templates and create a new template if an "application/json" does not exist, if it does just update it.

This is the important part, pass the header value you set in step 1. To do that write something similar to the following in the Template Box.

{
   "origin" : "$input.params().header.Origin",
   "host" : "$input.params().header.Host"
}

You can also pass in any url parameters you have defined in the same JSON.

  1. Access the data from Lambda, The integration request passed the information into the "Event" parameter if using Node as the Lambda Backend code. to retrieve the value of any header just use the following within your handler.

    event.origin;
    
  2. When sending back your response from Lambda to API Gateway, it is best to format the response in JSON. Something similar to this.

    { 
       "origin" : event.origin,
       "host" : event.host,
       "nonHeaderOutput" : "Hello World"
    }
    
  3. In "Integration Response" go to "Header Mappings", if the header you need is not listed you may add it in "Method Response" and it will then appear here. For this example I used "Access-Control-Allow-Origin" and edited the Mapping Value to be integration.response.body.origin

  4. now go to "Mapping Templates and select the content type you want to use, and then edit the template to access the non header responses by adding this to the Template Box

    $input.path("$.nonHeaderOutput")
    

That is it now the header that was sent to the API can be used in your method Response.

like image 72
wmfrancia Avatar answered Nov 15 '22 08:11

wmfrancia