Kong is introduced
Kong is a high availability gateway API written based on the Nginx_Lua module, which distributes requests evenly to each Server through pre-configured load balancing configuration to cope with a large number of network requests. Kong itself is also very easy to scale to multiple servers based on Nginx features.
Kong has three main components:
Kong Server: Nginx-based Server used to receive API requests. Apache Cassandra/PostgreSQL: Used to store operational data. Kong Dashboard: An official recommended UI management tool. You can also use restfull to manage the Admin API.Copy the code
Kong way of working
Basic Concepts of Kong:
Client: a downstream client sends a request to Kong's proxy port. Services: Service entities that are abstractions for each of their upstream services. Customer requests are forwarded to the service. Routing: Routing is the entry point into Kong and defines rules for requests to be matched and routed to the given Service. The relationship between services and routes is one-to-many. Plug-in: It is the business logic that runs in the agent life cycle. Plug-ins can be configured through the ADMIN API - global (all incoming traffic) or specific routes and services. User: is the credential for authentication when invoking the API serviceCopy the code
For more information, please refer to konghq.com/kong/
Install the configuration
The installation is based on docker. Docker installation please refer to Docker practice one Docker installation
1. Establish virtual network in Docker:
docker network create kong-net
Copy the code
Subsequent applications and databases use this virtual network.
Docker-comemage. yaml
version: "3.7"
services:
kong:
# Mirror version, current updateImage: kong: 1.1.2 environment:# Data persistence mode, using postgres database
- "KONG_DATABASE=postgres"
Database container name, which Kong uses to connect data
- "KONG_PG_HOST=kong-database"
# database name
- "KONG_CASSANDRA_CONTACT_POINTS=kong-database"
# log directory
- "KONG_PROXY_ACCESS_LOG=/dev/stdout"
- "KONG_ADMIN_ACCESS_LOG=/dev/stdout"
- "KONG_PROXY_ERROR_LOG=/dev/stderr"
- "KONG_ADMIN_ERROR_LOG=/dev/stderr"
# Exposed port
- "KONG_ADMIN_LISTEN = 0.0.0.0:8001, 0.0.0.0:8444 SSL"
ports:
- 8000:8000
- 8443:8443
- 8001:8001
- 8444:8444
# Use the Docker network
networks:
- kong-net
# Rely on database services
depends_on:
- kong-database
# Kong Admin interface
konga:
image: pantsel/konga
environment:
- "TOKEN_SECRET=51liveup.cn"
- "NODE_ENV=production"
ports:
- 8080:1337
networks:
- kong-net
depends_on:
- kong-database
-
# Database servicesKong-database: image: postgres:9.6 ports: -"5432:5432"
environment:
The user accessing the database
- POSTGRES_USER=kong
- POSTGRES_DB=kong
networks:
- kong-net
volumes:
# Sync time
- /etc/localtime:/etc/localtime:ro
# database persistence directory
- /data/data/postgresql:/var/lib/postgresql/data
networks:
kong-net:
external: true
Copy the code
Use the docker-compose up command to start the service. You’ll find an error starting The Times database because the Postgres data kong uses needs to be initialized before it can be used.
Initialize the database
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations bootstrap
Copy the code
After must create database container, and keep the database Docker container in running state, perform initialize database, after the success of the database initialization, again use the Docker – compose the up – d it is ok to start the service.
Verify the installation
Execute on the host
curl -i http://localhost:8001/
Copy the code
Return the following:
HTTP/1.1 200 OK Date: Mon, 17 Jun 2019 02:43:33 GMT Content-Type: Application /json; HTTP/1.1 200 OK Date: Mon, 17 Jun 2019 02:43:33 GMT Content-Type: Application /json; Charset = UTF-8 Connection: keep-alive access-Control-allow-Origin: * Server: kong/1.1.2 Content-Length: 5860....Copy the code
Indicates that the installation is correct. You can now use Kong normally.
Visit http://localhost:8080 To access Konga’s management interface, you need to create an administrator account and password for the first login.
For more information, see the installation documentation on the official website.
Configuring an instance
Configure an API for accessing www.baidu.com/. The IP address of the service data interface is connected to the backend.
1. Create a service
A service is an abstraction of an upstream service, which can be an application or a concrete interface.
Command line to create a service:
curl -i -X POST \
--url http://51liveup.cn:8001/services/ \
--data 'name=baidu-service' \
--data 'url=https://www.baidu.com/'
Copy the code
Konga’s admin interface for creating and viewing services is shown below
2. Create a route
Create a route on the bidu-service service you just created
curl -i -X POST \
--url http://51liveup.cn:8001/services/baidu-service/routes \
--data 'hosts[]=baidu.com' \
--data 'paths[]=/api/baidu'
Copy the code
3. Access data via Postman
= Host=baidu.com = Host=baidu.com = Host=baidu.com = Host=baidu.com = Host=baidu.com = Host=baidu.com = Host=baidu.com
Use of the JWT plugin
As long as we know the address of the Router, we can access the data. We will add the API to the authentication. If the API is not for specific users, but for other systems, JWT can be used for inter-system authentication, which is possible using the Kong JWT plug-in. The JWT plug-in is enabled on the corresponding Router.
curl -X POST http://51liveup.cn:8001/routes/fee36521-e549-410f-8986-9fbba02219c1/plugins \
--data "name=jwt"
Copy the code
Fee36521-e549-410f-8986-9fbba02219c1 is the ID of the created router.
Postman = Postman; Postman = Postman;
{
"message": "Unauthorized"
}
Copy the code
Client access requires JWT authentication information.
Create a user
curl -i -X POST \
--url http://51liveup.cn:8001/consumers/ \
--data "username=baiduuser"
Copy the code
The user generates JWT credentials
curl -i -X POST \
--url http://51liveup.cn:8001/consumers/baiduuser/jwt \
--header "Content-Type: application/x-www-form-urlencoded"
Copy the code
Returns the credential information. You can also query the credential information using the GET method
{
"rsa_public_key": null,
"created_at": 1560723665,
"consumer": {
"id": "8bb94f49-22a6-4d77-9a64-21f13adc0342"
},
"id": "a110d234-6dc1-4443-9da2-21acddc66e09"."algorithm": "HS256"."secret": "lCe8Lbb7F0KtLccaBcBnOvYg76V7wmQx"."key": "7yQoUdF0aFUC9N593uLQLbqL7RSPj2qM"
}
Copy the code
JWT. IO/generates JWT credential information using key and secret.
Access postman again, and you can see the data.
The following is an example of accessing data through Java code, which is not applicable to the interface of Baidu configured above.
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import okhttp3.*;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Base64;
public class Example {
public static void main(String[] args) {
Example example = new Example();
example.get("http://51liveup.cn:8000/api/xxxx/1");
}
public void get(String url) {
OkHttpClient mOkHttpClient = new OkHttpClient();
Request request = createBuilder().url(url).post(FormBody.create(MediaType.parse("application/json; charset=utf-8"), "{}")).build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("failure : \r\n" + e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println("response:"); System.out.println(response.body().string()); }}); } private Request.BuildercreateBuilder() {
Request.Builder builder = new Request.Builder();
builder.addHeader("host"."51liveup.cn");
builder.addHeader("Authorization"."Bearer " + generateJwt());
return builder;
}
private String generateJwt() {
String jwt = Jwts.builder()
.setHeaderParam("typ"."JWT")
.setHeaderParam("alg"."HS256")
.setIssuer("7yQoUdF0aFUC9N593uLQLbqL7RSPj2qM") // key
.signWith(SignatureAlgorithm.HS256, Base64.getEncoder().encodeToString("lCe8Lbb7F0KtLccaBcBnOvYg76V7wmQx".getBytes(Charset.forName("utf-8"))))
.compact();
System.out.println("jwt:" + jwt);
returnjwt; }}Copy the code
Use the ACL plug-in
The JWT plug-in can protect the API from being accessed by trusted users, but it cannot distinguish which users can access which API, that is, the interface permission problem, we use the ACL plug-in to solve this problem.
Enable the ACL plugin on the routes defined above, specify the whitelist,
curl -i -X POST \
--url http://51liveup.cn:8001/routes/afb8bfbd-977e-464f-8c94-05d6c5c98429/plugins \
--data "name=acl" \
--data "config.whitelist=baiduGroup"
Copy the code
Accessing the API at this point will prompt you that the service cannot be accessed.
{
"message": "You cannot consume this service"
}
Copy the code
Just associate the Baiduuser user to the baiduGroup in the whitelist.
curl -i -X POST \
--url http://localhost:8001/consumers/tianqiuser/acls \
--data "group=tianqi"
Copy the code
If the interface is accessed again, data can be returned normally.
You can now authenticate and control permissions on the interfaces exposed by the gateway.