Can you statically set a Header and it's value when setting up an HTTP Proxy using AWS Api Gateway endpoint? - amazon-web-services

I am creating an http proxy using AWS Api Gateway. I would like to hard code some of the headers and their values to be forwarded as part of the request. I thought this might be possible in the 'Integration Request' portion of the proxy setup, but I can't seem to figure it out.
I'm trying to pass an Authorization header with an oauth key. I don't want to share this key with clients that have access to this service, since I will only provide a subset of access to users of this specific endpoint.

In the Integration Request, you can configure a static header value to be sent to the integration endpoint by putting the value inside of single quotes, e.g. 'my_static_header_value'.

Is it a problem to put those hardcoded headers in the request body ? It not, you could just use a template (in the integration request screen) :
{
"hardcoded_header": "$input.params('hardcoded_header')"
}
Hope this helps.

Related

AWS API Gateway Integration Request setup automation

I am trying to use the AWS API Gateway+Swagger to route the request to my express backend. I can't figure out how to automate the setup of the integration request as the Swagger file has no details on it.
I'm also having difficulty with the endpoint url parameter when setting my method requests to GET/VPC Link on the integration type
For example:
My api gateway path is /info/car/{model}/aggregate
Now the endpoint url is http://carapi.com/info/car/{model}/aggregate
I have lots of gateway paths all of which are the same paths that my carapi.com site uses, so I don't want to keep retyping the path over and over. When entering in the endpoint url, I was able to simplify not having to type carapi.com by using stage variables turning my endpoint url to
http://${stageVariables.carApi}/info/car/{model}/aggregate
However after reading https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#stagevariables-template-reference
I see that there is also a $context available, but it gives me an error(when I try to call the api in postman, says 'internal server error' for the message) when I try to implement the context (which through that link shows that I can implement the path).
http://${stageVariables.carApi}/${context.resourcePath}
So my question is: how do I automate the setup of Integration requests so I don't have to manually setup each and every one(as I have hundreds of paths)? Is there also anyway to not have to set the paths manually for the endpoints?
I don't know of any solution which is ready to use.
In my project, we wrote a custom solution that downloads the application Swagger json, parses it, adds the required integration and generates another json file. Then we import that into API Gateway. This has been converted as a Jenkins job and runs as a post job of microservice deployment.
Another way is, instead of generating the json, directly call API Gateway APIs and add the integration.

How do I respond with a request header in AWS API Gateway

I have a POST request coming in with a header that I need to play back with the response (Example: "Validation: 123").
The integration returns synchronously, immediately.
The header is entirely non-functional and so doesn't need to be passed through to my integration. It just needs to be passed back with the response to the inbound request.
I am trying to do this by mapping the headers from the method request through to the method response, or via the integration request/response.
For example, I'd like to set the header mapping for the integration response to method.request.header.Validation (ie, identically to the integration request mapping). However, this is disallowed.
Is this the right approach?
This is a limitation of AWS API Gateway.

AWS API Gateway ERR_CONTENT_DECODING_FAILED in browser

In my use case, API Gateway serves as an HTTP proxy, using default settings following official tutorial.
It's tested working in test console or via curl. But if I access the link in browser or make an AJAX call, I'll get ERR_CONTENT_DECODING_FAILED.
It seems that API Gateway corrupt the content. Related issue.
Is there a way to forbid API Gateway changing my content? I set Content Handling to passthrough, but clearly it's changing my content.
Add a static integration request header Accept-Encoding with value 'identity', so that AWS won't tamper your request.

Setting CORS via API Gateway for Serverless Architecture Model Proxy Endpoint

I am working on a C#/.Net serverless application using the AWS Visual Studio Toolkit, and I am having a bit of trouble figuring out what I am missing as far as CORS configuration. I based my project off of the ASP.Net example included with the toolkit, which configured API Gateway to have a single API endpoint that works as a proxy into the ASP.Net Web API framework.
In testing this application in chrome (serving a local node project) I am getting No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
I know this means I have to configure CORS on the API Gateway endpoint, but I seem to be missing something. I use the actions dropdown to enable CORS as such...
But I get some errors and the problem persists.
I used a chrome extension to disable CORS (temporarily) and have confirmed that the API endpoint works normally without CORS.
So what am I missing here? The examples of setting CORS online don't usually have instructions of a catch-all endpoint like this is set up to use, and even breaking GET into its own method didn't seem to help.
As an additional question, if there is some CORS configuration I am missing, is there a good way to get it integrated into the serverless.template file or some other automated deploy step?
It has to do with your ANY proxy method. As stated here: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
Note
When applying the above instructions to the ANY method in a proxy integration, any applicable CORS headers will not be set. Instead, you rely on the integration back end to return the applicable CORS headers, such as Access-Control-Allow-Origin
So you will have to make your backend API return the appropriate CORS headers.
You need to have the header on your server as well as the api gateway.
See this sample: - The cors header is applied to the static bucket website
https://www.codeproject.com/Articles/1178781/Serverless-Architecture-using-Csharp-and-AWS-Amazo
For the APIs to work properly two things must be done:
1. The options method must be correctly setup - usually done using a mock method on the API gateway.
2. The HTTP method implementations in your code must return the CORS header correctly. There are quite a few articles about this if you search.
For me the problem was Point 1; using the API Gateway 'Enable CORS' button did not work for me when I was developing API-Gateway Lambda integration using .NET Core. I also didn't find a way to add creation of the options method in the serverless.template file.
Here's another way to do it; after publishing the lambdas from CLI or VisualStudio, fire a PUT request on the API endpoint and pass a swagger definition which contains the options method defs and ensure you set the query param mode=merge. You can use PostMan to do this.
or
You use a DotNet utility which does the same thing explained here:
http://sbytestream.pythonanywhere.com/blog/Enabling-APIGateway-CORS
The source code is available on GitHub too.

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
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.
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
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"
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.
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;
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"
}
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
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.
Jurgen from API Gateway here.
Thanks for reporting this issue. There is currently no simple way to set it up via the "Enable CORS" feature in the console. However, we are looking into it to improve the user experience for this use case.
As a potential workaround, you could passthrough the Origin header from the client to your backend and parse / create the value for the Access-Control-Allow-Origin header there. Then you would map the Header in the Integration Response from 'integration.response.header.Access-Control-Allow-Origin' to Access-Control-Allow-Origin and return it to the client.
Hope this helps.
Best,
Jurgen