This is a continuation of the Serverless Reservation application started in previous posts.
There should be nothing simpler than securing the API with API key passed in request header.
Servlerless documentation states that it already supports it without additional coding.
All we need to do is to update handler definition in serverless.yml
functions:
graphQl:
handler: index.graphql
memory: 512
timeout: 3
events:
- http:
path: graphql
method: post
private: true
We’ve just added private: true
.
This tells Serverless to expect API key in header.
How do we set which key to use?
Again, we need to update serverless.yml
provider:
name: aws
runtime: nodejs4.3
stage: dev
profile: dev_profile
apiKeys:
- secret
We have added apiKeys
param in the provider definition, secret
is the name of the key.
If we had multiple API keys we could identify them by name and distribute to multiple users so that each of them has own key.
The header which clients should pass in each request must be always x-api-key
because Amazon does not support custom names at the moment - see this discussion.
Let’s test it.
We will use the code developed in previous blogpost. When we deploy the application it will print out the generated value for the API key to use in header. The same we can get with command:
sls info
wich gives information like:
...
api keys:
secret: rKGHEryMVF6EvmXF4VzGzSv1xy7Jk3d7KjREL5Fg
...
Then we use Curl to test it:
- without API key
curl -X POST \
-H "Content-Type: application/json" \
-d '{items(name: "demo item") {name, createdAt}}' \
<endpoint URL>
In the above command we need to replace <endpoint URL>
with the real URL of API Gateway which should be printed out from the serverless deploy
command.
The response which we should get is: Forbidden
- with API key
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: rKGHEryMVF6EvmXF4VzGzSv1xy7Jk3d7KjREL5Fg" \
-d '{items(name: "demo item") {name, createdAt}}' \
<endpoint URL>
Booo..! this time we get the same error. It does not work. There is an open issue already. We need extra manual work to add the API key created in CloudFormation by Serverless framework to usage plan. This page explains very well how to configure Usage Plan on AWS.
When we login to AWS console and navigate to API Gateway panel we can see that our API Key is already present
but Usage Plan is empty so we need to create it.
Here is how we do it:
- Click Create button and fill in the form
Click Next.
- Choose API and Stage - we have only one of each so it should not be confusing.
We cannot continue further because the little orange triangle next to selected API shows an error that not all resources in the API are secured with a key. This is because our former /hello endpoint is not secured. As we’re not going to need it anymore we can just delete it and come back to Usage Plan creation.
Go to Resources, select ‘/hello’ and in Actions dropdown select ‘Delete Resource’
Then come back to Usage Plan and assign API to Stage again
This time it succeeds. Then go to second tab and select API key.
Now we should be able to request endpoint successfully, check again:
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: rKGHEryMVF6EvmXF4VzGzSv1xy7Jk3d7KjREL5Fg" \
-d '{items(name: "demo item") {name, createdAt}}' \
<endpoint URL>
The code for this post can be found at Github
References
comments powered by Disqus