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.