I'm using AWS API Gateway to create an api.
I have the following path for an API: /users/{id}
Is there a way to validate the existence of id in the API request made and maybe its type in API Gateway before it reaches the Lambda integration? I understand API Gateway supports validating request body, query params and headers, but I can't see any option for path parameters, does API Gateway not support that?
I'm going through the documentation and I can't seem to find something clear on that.
API Gateway can check if a path parameter exists or not. It can check if path includes any "id", but it cannot for example check what is it’s regex pattern. Such validation should be made on a client side. Either the API Gateway path follows the defined pattern, in which case it can route you to an appropriate resource, or not. It can however ensure that request parameters are present and non-blank.
The AWS documentation states that API Gateway can perform the basic validation:
API Gateway can perform the basic validation. This enables you, the
API developer, to focus on app-specific deep validation in the
backend. For the basic validation, API Gateway verifies either or both of the following conditions:
The required request parameters in the URI, query string, and headers of an incoming request are included and non-blank.
The applicable request payload adheres to the configured JSON schema request model of the method.
To enable basic validation, you specify validation rules in a request validator, add the validator to the API's map of request validators, and assign the validator to individual API methods.
Note that comparison with JSON schema request model refers to the request payload, and not to request parameters. In the documentation you can find guidance on how to enable request validation in API Gateway:
by importing OpenAPI
definition
using the API Gateway REST
API
using AWS
console
Also, follow this blog post which explains how to set up request parameters validation. Mind however, that the basic validation ensures that the request parameters are present and non-blank. More advanced validation, like checking regex pattern or type, is not possible to my knowledge.
Hello: I've been following two tutorials in the AWS documentation:
creating the sample pet store API (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-from-example.html)
...and creating an API key (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-setup-api-key-with-console.html#api-gateway-usage-plan-create-apikey).
When I test the pet store get method with the provided URL, it returns:
Welcome to your Pet Store API You have successfully deployed your
first API. You are seeing this HTML page because the GET method to the
root resource of your API returns this content as a Mock integration.
The Pet Store API contains the /pets and /pets/{petId} resources. By
making a GET request to /pets you can retrieve a list of Pets in your
API. If you are looking for a specific pet, for example the pet with
ID 1, you can make a GET request to /pets/1.
You can use a REST client such as Postman to test the POST methods in
your API to create a new pet. Use the sample body below to send the
POST request:
{
"type" : "cat",
"price" : 123.11 }
Now I go to the API Gateway -> API -> Resources -> -> Method Request -> API Key Required and change it to "True" and redeploy.
When I go to the provided URL to test, now the page returns:
{"message":"Forbidden"}
Which makes sense... I told it API required = true, right?
So my question is, how do I pass the API key? So that I don't get the "forbidden" result? I didn't see that in the tutorial links I pasted above and haven't been able to find elsewhere.
You Create a Usage Plans
Attach this usage plan to your API and Stage
Create an API Key
Now invoke your API with header named x-api-key and value of it is the API Key created in step-3
Sample:
curl -i -H "x-api-key: Cd2YiWs8Fv8Lg6njI0wXf1iiNOE94XjM3EQe8567" -X GET https://7r9cvghbf4.execute-api.ap-northeast-2.amazonaws.com/dd/pets
Assuming you've followed all steps for creating the API key you can use this API key by specifying it in the x-api-key header within your request.
You distribute API keys to your customers and require them to pass the API key as the X-API-Key header of each incoming request.
More information for using API keys in API Gateway is available on: Choose an API key source - Amazon API Gateway
When using API-keys and usage plans for AWS API-gateway - is usage plan used even though the authorization method is not using API-keys (I would still pass x-api-key http header to the API)?
I ran into the same question, but I did not find the answer so I did some testing myself. This is what I found: Even if a method is not API Key required, any request sent to the method with API key in header will subject to the usage plan which is associated API key.
The test I did is:
create method A and set requireApiKey to false
set the rate and burst throttling values to 0 for a method A under a usage plan
associate an APIKey K with the usage plan
sent request through PostMan to method A with including K in header, resulted "Too Many Requests" error
sent request through PostMan to method A without including K in header, request succeeded.
I have created an API Key and added it to my functions. I have then deployed the api and tested it but still get:
"message": "Forbidden"
How do I pass the api key with my JSON request as I have been using "x-api-key": "theKey"?
The x-api-key parameter is passed as a HTTP header parameter (i.e. it is not added to the JSON body). How you pass HTTP headers depend on the HTTP client you use.
For example, if you use curl and assuming that you POST the JSON payload, a request would look something like (where you replace [api-id] with the actual id and [region] with the AWS region of your API):
$ curl -X POST -H "x-api-key: theKey" -H "Content-Type: application/json" -d '{"key":"val"}' https://[api-id].execute-api.[region].amazonaws.com
I had to add an API Usage plan, and then link the plan to the API stage.
Seems like this is the only way to link the key to the API, not sure if this is a recent change on AWS.
If you set 'API Key Required' option to true, please check below.
you have to pass 'x-api-key' HTTP Header Parameter to API Gateway.
The API Key had to be created.
In addition, you need to check a Usage Plan for the API Key on API Gateway Console.
If you set 'API' key required to true, you need to pass the api key as header.
API Key is passed as header field 'x-api-key'. Even after adding this field in header, this issue may occur. In that case, please validate below points
Do you have a Usage Plan? if not need to create one.
Link you API with Usage Plan. For that add a stage, it will link your API
Do you have API Key? if not you need to create an API Key and enable it.
Add the Usage Plan which is linked with your API to this API Key. For that, add Usage Plan.
I hope you are not missing to link the API key with the API
I was able to get a successful response from Lambda using below configuration in Postman native app -
Under authorization tab (For some reason this didn't work when i passed the same parameters under header)
Key : x-api-key
Value : your-api-key-value
Add to : Header
I don't have enough reputation to set this as a comment, But I was finally able to find the document specifying that 'x-api-key' belongs in the header for API Gateway calls that come from outside clients (like postman, swagger, etc.) in the AWS Documentation.
The relevant part:
To use header-sourced API keys:
Create an API with desired API methods. And deploy the API to a
stage.
Create a new usage plan or choose an existing one. Add the deployed
API stage to the usage plan. Attach an API key to the usage plan or
choose an existing API key in the plan. Note the chosen API key
value.
Set up API methods to require an API key.
Redeploy the API to the same stage. If you deploy the API to a new
stage, make sure to update the usage plan to attach the new API
stage.
The client can now call the API methods while supplying the x-api-key
header with the chosen API key as the header value.
Choose an API key source
For Private API Gateways accessed through public DNS, we need to pass additional header of 'x-apigw-api-id' with the api id along with 'x-api-key' if configured.
curl -v https://{vpce-id}.execute-api.{region}.vpce.amazonaws.com/test -H 'x-apigw-api-id:{api-id}'
Its documented below,
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html#w20aac13c16c28c11
Here a good resource explaining different reasons why we could be getting a Forbidden. The two most important are the request URL and the x-api-key header:
https://{api_id}.execute-api.{region}.amazonaws.com/{stage_name}/{resource_name}
Missing stage name will give you 403 for ex. Maybe for security reasons the response is not revealing an issue with the stage name, and thus you get a generic Forbidden.
I faced the same problem today. I had already mapped the API key to the usage plan (which was linked to the api gateway stage). I was also passing the api key in header correctly.
When none of these solutions work, do remember to check if your API is linked to WAF policy with only a certain ip-addresses permitted. Apparently, my IP address had changed today. So, WAF was blocking me. That can be an additional reason to get {"message": "Forbidden"} error.
I am using amazon's itemlookup api to get the details of an book provided the ISBN has been given to it.
I have made an request to Amazon aws with URL as:
http://webservices.amazon.com/onca/xml?AWSAccessKeyId=access_key&Keywords=0439708184&Operation=ItemSearch&ResponseGroup=ItemAttributes%2COffers&SearchIndex=Books&Service=AWSECommerceService&Timestamp=2015-03-23T16%3A04%3A21Z&Version=2009-01-06&Signature=hashed_signature
And all I get from above request is :
<Message>Your request is missing required parameters. Required parameters include AssociateTag.</Message>
Later on, I have generated an AssociateTag for myself and passed it to the the query string but that did not help either. Instead, it gave me another message that "Signature does not match."
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message>
After adding the associate tag, my query string looks like as:
http://webservices.amazon.com/onca/xml?AWSAccessKeyId=access_key&Keywords=0439708184&Operation=ItemSearch&ResponseGroup=ItemAttributes%2COffers&SearchIndex=Books&Service=AWSECommerceService&Timestamp=2015-03-23T16%3A04%3A21Z&Version=2009-01-06&AssociateTag=hemant-20&Signature=hashed_signature
Am I missing anything basic here?