Kong as API Gateway support for configurable plugin, to get what is Kong and basic tutorial to install and setup KONG you could go to this article.
Now we through how to setup Oauth2 to our Kong, but before that it is required to through previous tutorial.
Please make sure you have installed and setup KONG, and it’s up and running. You should have this:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
272841a859d2 node_kong “npm start” 3 days ago Up 15 hours 10000/tcp node_kong
2bd5d4b0126b kong:latest “/docker-entrypoint.…” 3 days ago Up 15 hours 0.0.0.0:9000->8000/tcp, 0.0.0.0:9001->8001/tcp, 0.0.0.0:9443->8443/tcp, 0.0.0.0:9444->8444/tcp kong
92877820c824 postgres:9.6 “docker-entrypoint.s…” 3 days ago Up 15 hours 0.0.0.0:5555->5432/tcp kong-database
and we could access the API through KONG (localhost with port 9000):
GET: localhost:9000/api/v1/customers
Headers: Host:api.ct.id
Respond:
[
{
“id”: 5,
“first_name”: “Dodol”,
“last_name”: “Dargombez”
},
{
“id”: 6,
“first_name”: “Nyongot”,
“last_name”: “Gonzales”
}
]
So we already have KONG as API gateway connected to upstream service as own API/service to get customers. Now we go through to try plugin that can be as sidecar on API-gateway.
To make it easier if you have not done yet, please download file kong.postman_collection.json on github NodeJS-API-KONG (https://github.com/faren/NodeJS-API-KONG), and import it to postman.
We are going to explore the expanded folder postman above.
Enabling the plugin on a service
For this example, we have a service api-v1-customers. Hit the GET API KONG services:
GET: localhost:9001/services/
Respond:
{
“next”: null,
“data”: [
{
“host”: “172.19.0.4”,
“created_at”: 1531989815,
“connect_timeout”: 60000,
“id”: “d28c20e4–94d3–4c3b-9a0d-688ac8dbf213”,
“protocol”: “http”,
“name”: “api-v1-customers”,
“read_timeout”: 60000,
“port”: 10000,
“path”: null,
“updated_at”: 1531989815,
“retries”: 5,
“write_timeout”: 60000
}
]}
So, we enable this service to Oauth2 plugin by hit API method POST for add service to plugin:
POST: localhost:9001/services/api-v1-customers/plugins
Headers: Content-Type:application/json
Body:
{
“name”: “oauth2”,
“config.scopes”: [“read”, “write”],
“config.mandatory_scope”: true,
“config.enable_password_grant”: true,
“config.accept_http_if_already_terminated”: true,
“config.token_expiration”: 180,
“config.global_credentials”: true
}Respond:
{
“created_at”: 1532406761000,
“config”: {
“refresh_token_ttl”: 1209600,
“scopes”: [
“read”,
“write”
],
“mandatory_scope”: true,
“enable_client_credentials”: false,
“accept_http_if_already_terminated”: true,
“token_expiration”: 180,
“enable_implicit_grant”: false,
“global_credentials”: true,
“anonymous”: “”,
“enable_password_grant”: true,
“hide_credentials”: false,
“enable_authorization_code”: false,
“provision_key”: “kl3bUfe32WBcppmYFr1aZtXxzrBTL18l”,
“auth_header_name”: “authorization”
},
“id”: “4f1dbb44-bb51–49b3–80d5-b0a5ac4f7caf”,
“enabled”: true,
“service_id”: “eb422ef1–65a3–4654-a75f-41a8132d7861”,
“name”: “oauth2”
}
Create a consumer
After enable plugin to specific service on this case service customers, now time to add a consumer who can access the API. You need to associate a credential to an existing Consumer object.
POST: localhost:9001/consumers
Headers: Content-Type:application/json
Body:
{
“username”: “oneone@gmail.com”,
“custom_id”: “11”
}Respond:
{
“custom_id”: “11”,
“created_at”: 1532416069,
“username”: “oneone@gmail.com”,
“id”: “6db1dfe5–47f2–455b-8fb0-d935017efcb3”
}
Create an application
Then you can finally provision new Oauth2 credential (also called :OAuth applications”) by making the following hit API POST, as follow:
POST: localhost:9001/consumers/oneone@gmail.com/oauth2
Headers: Content-Type:application/json
Body:
{
“name”: “APP 11”,
“client_id”: “CLIENT_ID_11”,
“client_secret”: “CLIENT_SECRET_11”,
“redirect_uri”: “http://localhost:9800/cb"
}Respond:
{
“client_id”: “CLIENT_ID_11”,
“created_at”: 1532419699000,
“id”: “06acbdce-08f5–40fd-95f5–52cdad2b6d06”,
“redirect_uri”: [
“http://localhost:9800/cb"
],
“name”: “APP 11”,
“client_secret”: “CLIENT_SECRET_11”,
“consumer_id”: “6db1dfe5–47f2–455b-8fb0-d935017efcb3”
}
Once we have activated service “api-v1-customer” Oauth2, we could not access the API without Authorisation, let’s try again hit API customer:
GET: localhost:9000/api/v1/customers
Headers: Host:api.ct.id
Respond:
{
“error_description”: “The access token is missing”,
“error”: “invalid_request”
}
Request and Refresh Token
We have add consumer and create application for specific consumer (ex: oneone@gmail.com) to OAuth plugin service api-v1-customer. Now we need to simulate to get token and refresh token as part of OAuth 2.0 Flows to access API that has been protected Oauth2.
POST: https://localhost:9443/api/v1/customers/oauth2/token (warning: please make sure it’s https, you can set ignore it from postman on setting, SSL certificate verification set to OFF)
Headers: Content-Type:application/json
Host:api.ct.id
Body:
{
“client_id”: “CLIENT_ID_11”,
“client_secret”: “CLIENT_SECRET_11”,
“grant_type”: “password”,
“provision_key”: “kl3bUfe32WBcppmYFr1aZtXxzrBTL18l”,
“authenticated_userid”: “oneone@gmail.com”,
“scope”: “read”
}Respond:
{
“refresh_token”: “halEdslDD61bTvMxUGbPbu75DxdKmWdP”,
“token_type”: “bearer”,
“access_token”: “UYSLDGIZI8yIotLryGRp93jvF1YsYdHB”,
“expires_in”: 180
}
When we enable OAuth2 plugin to api-v1-customer service, we set token expired for 180 seconds. So after 180 seconds, the token is expired, and need to refresh token, by:
POST: https://localhost:9443/api/v1/customers/oauth2/token (warning: please make sure it’s https, you can set ignore it from postman on setting, SSL certificate verification set to OFF)
Headers: Content-Type:application/json
Host:api.ct.idBody:
{
“grant_type”: “refresh_token”,
“client_id”: “CLIENT_ID_11”,
“client_secret”: “CLIENT_SECRET_11”,
“refresh_token”: “halEdslDD61bTvMxUGbPbu75DxdKmWdP”
}Respond:
{
“refresh_token”: “YEtNrtkKXw0KoRahZttDC43YgPPcpOfm”,
“token_type”: “bearer”,
“access_token”: “FTthUuOiTU1o2m4F8DUaWDsacbm3Fbam”,
“expires_in”: 180
}
So now, we have token and we could put on header key — Authorization: bearer token
GET: localhost:9000/api/v1/customers
Headers: Host:api.ct.id
Authorization:bearer UYSLDGIZI8yIotLryGRp93jvF1YsYdHBRespond:
[
{
“id”: 5,
“first_name”: “Dodol”,
“last_name”: “Dargombez”
},
{
“id”: 6,
“first_name”: “Nyongot”,
“last_name”: “Gonzales”
}
]
Conclusion
Plugin Oauth2 is one of the common authorisations that used nowadays. Kong has provided this plugin and manage it by API for community edition. However to get more understanding on Oauth 2.0 Flows, you need to understand the concept itself, please read more about this on https://docs.konghq.com/plugins/oauth2-authentication