Introduction to Kong API Gateway

Introduction

Kong is an open source API Gateway that sits in front of you RESTful API. You can extend Kong using plugins. Out of the box you manage and configure Kong using a RESTful API. This can be a bit cumbersome but there are 3rd party frontends which can help make managing Kong a little bit easier.

In this introduction to Kong we will explain what an API Gateway is, download and setup a Kong Docker container, and install the Key Authentication plugin to secure the API for our consumers.

We will be using the Open Weather Map free tier API for this demonstration.

What is an API Gateway?

Put simply, an API gateway is a filter that sits in front of your RESTful API. This gateway can be hosted by you or a third party. Typically, the gateway will provide one or more of the following:

  • Access control- only allow authenticated and authorized traffic
  • Rate limiting - restrict how much traffic is sent to your API
  • Analytics, metrics and logging – track how your API is used
  • Security filtering – make sure the incoming traffic is not an attack
  • Redirection – send traffic to a different endpoint

Here is a simple diagram showing a typical workflow using Kong:

Client’s make requests to your API by going through Kong first. Kong will proxy your requests to the final API and will execute all plugins that you have setup. For example, if you have the rate limit plugin installed Kong will check and make sure the request doesn’t exceed the specified limits before calling your API.

Prerequisites

  • Docker – make sure you have Docker installed and have some idea of how to use it.
  • Open Weather Map – We will be using the Open Weather Maps free tier API for this demo. You will need to sign up for a free account in order to get an API Key needed to call their services: https://home.openweathermap.org/users/sign_up

Nice to have

  • Kong Dashboard – a UI tool for managing your Kong Gateway. https://github.com/PGBI/kong-dashboard. This demo will show you how to use the Kong API for creating your API, consumers and installing plugins. However, this UI does make managing Kong a bit easier.
  • Kitematic for Docker – Makes it a bit easier to run Docker containers in a simple UI: https://kitematic.com

Setup

Kong has a nice write up on how to use Kong in Docker: https://getkong.org/install/docker/ This is just a summary of what is on this page.

 

For this example, I setup the Cassandra container:

$ docker run -d --name kong-database \
-p 9042:9042 \
cassandra:2.2

Next start Kong:

$ docker run -d --name kong \
--link kong-database:kong-database \
-e "DATABASE=cassandra" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 7946:7946 \
-p 7946:7946/udp

A few notes about the ports:

  •  8000 – non-SSL enabled proxy layer for API requests.
  • 8443 – SSL enabled proxy for API requests.
  • 8001 – RESTful Admin API for configuration. You will use this port to administrate your Kong installation.
  • 7946 – This is used for Kong clustering

Finally, call the admin endpoint to verify Kong is running:

$ curl http://127.0.0.1:8001

Add Open Weather Map API

First we need to create an API object in Kong to describe the API that we are going to expose to consumers.

Let’s go ahead and create the API using the administration API and port:

Request:

$ curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'name=openweathermap.org' \
--data 'upstream_url=http://api.openweathermap.org/data/2.5' \
--data 'request_host=api.openweathermap.org'

Response:

{
"created_at": 1463423154000,
"id": "d736abb8-3a8b-451f-84b0-e85f5e53e907",
"name": "openweathermap.org",
"preserve_host": false,
"request_host": "api.openweathermap.org",
"strip_request_path": false,
"upstream_url": "http://api.openweathermap.org/data/2.5"
}

Now let’s use the administration API to confirm the Weather API was added successfully:

Request:

$ curl --url http://localhost:8001/apis

Response:

{
"data": [
{
"created_at": 1463423154000,
"id": " d736abb8-3a8b-451f-84b0-e85f5e53e907",
"name": "openweathermap.org",    
"preserve_host": false,
"request_host": "api.openweathermap.org",
"strip_request_path": false,
"upstream_url": "http://api.openweathermap.org/data/2.5"
}
],
"total": 1
}

Make a note of the “id” for this API (d736abb8-3a8b-451f-84b0-e85f5e53e907 in this example). We will be using this later to add a plugin to it.

Tip:

If you are running on a Mac, you can pipe the output through Python to pretty print the JSON output:

$ curl --url http://localhost:8001/apis | python -m json.tool

Test

Let’s go ahead and verify we can call the API we just registered. Be sure to replace <key> with the API key you created after registering with Open Weather Mapper.

Note that we are using the proxy requests on port 8000 to make the call to the API. Kong will forward the request to the “upstream_url” we defined when creating the API.

The “Host” header is used by Kong to know which API to forward to.

Request:

$ curl -v 'http://localhost:8000/weather?q=London&APPID=<key>' \
--header 'Host: api.openweathermap.org'

Example response:

{
"base": "cmc stations",
"clouds": {
"all": 0
},
"cod": 200,
"coord": {
"lat": 51.51,
"lon": -0.13
},
"dt": 1463422447,
"id": 2643743,
"main": {
"grnd_level": 1022.25,
"humidity": 51,
"pressure": 1022.25,
"sea_level": 1032.14,
"temp": 290.005,
"temp_max": 290.005,
"temp_min": 290.005
},
"name": "London",
"sys": {
"country": "GB",
"message": 0.0153,
"sunrise": 1463371538,
"sunset": 1463428149
},
"weather": [
{
"description": "clear sky",
"icon": "01d",
"id": 800,
"main": "Clear"
}
],
"wind": {
"deg": 316.003,
"speed": 4.58    
}
}

Install Key Authentication Plugin

Now let’s start locking down the API. We don’t want non-authenticated clients accessing it! Here is an easy key authentication plugin for Kong:

https://getkong.org/plugins/key-authentication/

To install the plugin, we use the following which attaches it to the API. Notice that we are using the “id” of the API we created from above:

$ curl -X POST http://localhost:8001/apis/d736abb8-3a8b-451f-84b0-e85f5e53e907/plugins \

--data "name=key-auth"

Response:

{
"api_id": "d736abb8-3a8b-451f-84b0-e85f5e53e907",
"config": {
"hide_credentials": false,
"key_names": [
"apikey"
]
},
"created_at": 1463497899000,
"enabled": true,
"id": "6ab3cbf1-8e43-4ce3-938f-b137415eee9b",
"name": "key-auth"
}

Test authentication now required

Now let’s make sure our API is secure. Make the following request again making sure you replace the “<key>” with your key:

 

$ curl -v 'http://localhost:8000/weather?q=London&APPID=<key>' \
--header 'Host: api.openweathermap.org'

Notice we now get a 401 response:

< HTTP/1.1 401 Unauthorized

Add a Consumer

In order to use the API now, we will need to create a consumer and add a key.

Request:

$ curl -X POST http://localhost:8001/consumers --data "username=jack" --data "custom_id=1234"

Response:

{"custom_id":"1234","username":"jack","created_at":1463498578000,"id":"4ab3062d-b72b-40db-b6b9-e7c9f7dabee7"}

Now let’s add a key to this new consumer. Note that I had to add an empty body to the POST otherwise Kong would return a 415 Unsupported Media Type:

$ curl -X POST http://localhost:8001/consumers/jack/key-auth --data ""

Response:

{
"consumer_id": "4ab3062d-b72b-40db-b6b9-e7c9f7dabee7",
"created_at": 1463498984000,
"id": "b92d911c-5604-4c37-8130-48a159004755",
"key": "a025d31f90eb48d6a4eb88cd22df6f98"
}

Note that the plugin auto-generated a key for us. Make note of the “key” as we will need that in order to call the API. We could have passed in a key in the body of the request if we wanted to.

Test

Now let’s make sure this consumer can access the API using their API key generated from above. We need to pass in a new “apikey” header with the key.

$ curl -v 'http://localhost:8000/weather?q=London&APPID=<key>' \
--header 'Host: api.openweathermap.org' \
--header ‘apikey: a025d31f90eb48d6a4eb88cd22df6f98’

Congratulations!

Conclusion

I hope this simple tutorial has shown how Kong is easy to run (thanks Docker!) and manage using Kong management API. Kong plugins offer a lot of flexibility and customization for your APIs and the optional Kong Dashboard makes managing Kong a bit easier than having to use curl. Not too bad for an open source project!

Links