1. 概述
“如下 Kong 简介的内容,基于 Kong Github、Kong 官方文档、《API 网关之 Kong 简介》梳理~ 另外也推荐下 Kong 的“竞品” APISIX,一款国产的微服务 API 网关,目前已经进入 Apache 中孵化。想要学习的胖友,可以点击传送门学习!
Kong 是由 Mashape 公司开源的云原生、高性能、可扩展的微服务 API 网关。它基于 OpenResty 实现,使用 Cassandra 或 PostgreSQL 存储数据。
Kong Logo
- OpenResty:通过 Lua 扩展 Nginx 实现的可伸缩的 Web 平台。
- Cassandra:Key/Value 存储系统。
- PostgreSQL:数据库服务器。
Kong 整体
- Kong 提供了 RESTful Admin API,可用于管理员进行 Kong 的配置。
1.1 特性
Kong 网关具有以下的特性:
- 可扩展性:通过简单地添加更多的服务器,可以轻松地进行横向扩展,这意味着您的平台可以在一个较低负载的情况下处理任何请求。
- 模块化::可以通过添加新的插件进行扩展,这些插件可以通过 RESTful Admin API 轻松配置。 “在 https://docs.konghq.com/hub/ 地址下,可以看到 Kong 内置了丰富的插件。
- 在任何基础架构上运行:Kong 网关可以在任何地方都能运行。可以在云或内部网络环境中部署 Kong,包括单个或多个数据中心设置,以及 public,private 或 invite-only APIs。 “在 https://konghq.com/install/ 地址中,可以看到 Kong 支持在各种环境下的安装。
1.2 架构
Kong 的整体架构如下所示:
Kong 整体架构
“友情提示:自上往下看哈~注意加粗部分的字!
- Kong RESTful 管理 API,提供了 API、API消费者、插件、upstreams、证书等管理。
- Kong 插件拦截请求/响应,类似于 Java Servlet 中的过滤器,实现请求/响应的 AOP 处理。
- Kong 数据存储用于存储 Kong 集群节点信息、API、消费者、插件等信息,目前提供了 Cassandra 和 PostgreSQL 支持。如果需要高可用,建议使用 Cassandra。
- Kong 集群中的节点通过 gossip 协议自动发现其它节点。当通过一个 Kong 节点的管理 API 进行一些变更时,也会通知其他节点。每个 Kong 节点的配置信息是会缓存的,例如插件,那么当在某一个 Kong 节点修改了插件配置时,需要通知其他节点配置的变更。
- Kong 核心基于 OpenResty,使用 Lua 进行请求/响应的处理。
1.3 插件
Kong 内置了丰富的插件,提供了强大的功能以及集成能力,同时我们又可以基于插件机制自行进行拓展。
插件体系
- Authentication 身份认证插件:Kong 提供了 Basic Authentication、Key authentication、OAuth2.0 authentication、HMAC authentication、JWT、LDAP authentication 等等实现。
- Security 安全控制插件:ACL(访问控制)、CORS(跨域资源共享)、动态SSL、IP 限制、爬虫检测等等实现。
- Traffic Control 流量控制插件:请求限流(基于请求计数限流)、上游响应限流(根据 upstream 响应计数限流)、请求大小限制等等实现。限流支持本地、Redis 和集群三种限流模式。
- Analytics & Monitoring 分析监控插件:对接 Datadog、Prometheus、Zipkin 等等监控系统的实现。
- Transformations 协议转换插件:请求转换(在转发到 upstream 之前修改请求)、响应转换(在 upstream 响应返回给客户端之前修改响应)。
- Logging 日志应用插件:支持 TCP、UDP、HTTP、File、Syslog、StatsD、Loggly 等等方式传输日志。
- Serverless 插件:提供对 AWS Lambda、Azure Functions、Apache OpenWhisk、Kong 自带 Serverless Functions 等等的 Serverless 解决方案的支持。
- Deployment 插件
1.4 请求流程
为了更好地使用 Kong 网关,我们需要理解它处理 API 接口的典型请求工作流程:
请求流程
Kong 是每个 API 请求的入口点(Endpoint):
- 当 Kong 运行时,每个对 API 的请求将先被 Kong 命中,然后这个请求将会被代理转发到最终的 API 接口。
- 在请求(Requests)和响应(Responses)之间,Kong 将会执行已经事先安装和配置好的插件,授权 API 访问操作。
2. 快速安装
在《Kong 文档 —— 安装》下,官方提供了多种安装方式,这里我们采用 CentOS 系统。
Kong 安装方式
“友情提示:如果胖友会使用 Docker 的话,安装起来会比较便捷,可参考如下文章:
- 《Kong 与 Konga 之 Docker 部署》
- 《Kong 文档 —— Docker 方式安装》
2.1 安装 PostgreSQL
相比 Cassandra 来说,我们会更加熟悉 PostgreSQL,所以我们采用 PostgreSQL 作为 Kong 的数据存储。在《Kong 文档 —— CentOS 安装》提到,PostgreSQL 最低要求 9.5 版本,这里我们采用 12 版本。
“友情提示:如下所有的命令行操作,是在 root 用户下执行。如果胖友使用非 root 用户,请额外增加 sudo 命令。
2.1.1 安装
① 打开《PostgreSQL 文档 —— CentOS 安装》,选择 PostgreSQL 12 CentOS 7 后获得安装方式。如下图所示:
PostgreSQL 安装步骤
② 执行如下命令,进行 PostgreSQL 的安装:
代码语言:javascript复制# 添加 PostgreSQL 的 RPM
$ yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# 安装 PostgreSQL Server 12
$ yum install postgresql12-server
# 初始化数据库
$ /usr/pgsql-12/bin/postgresql-12-setup initdb
PostgreSQL 安装成功
③ 执行如下命令,进行 PostgreSQL 的启动:
代码语言:javascript复制# 设置 PostgreSQL 开机启动服务
$ systemctl enable postgresql-12
# 启动 PostgreSQL 服务
$ systemctl start postgresql-12
# 查看 PostgreSQL 状态
$ systemctl status postgresql-12
PostgreSQL 启动成功
2.1.2 配置
安装完成之后,会自动创建如下:
- 在 Linux 中,创建一个 Linux 系统用户
postgres
【管理 PostgreSQL 数据库的系统管理员】。 - 在 PostgreSQL 中,创建 PostgreSQL 用户
postgres
【数据库超级管理员】,以及数据库postgres
【用户postgres
的默认数据库】。
① 使用 passwd postgres
命令,我们来初始化下 postgres
用户的密码。详细如下图所示:
修改 postgres
用户的密码
② 为了安全以及满足 Kong 初始化的需求,需要创建一个 Linux 用户 kong
,并创建对应的 PostgreSQL 用户 kong
和数据库 kong
。操作命令如下:
# 创建一个 Linux 用户 `kong`
$ adduser kong
# 切换到 Linux 系统用户 `postgres`,因为它是 PostgreSQL 数据库的系统管理员
$ su postgres
# 进入 PostgreSQL 控制台
$ psql
# 设置用户 `postgres` 的密码【仅仅首次需要】
$ password postgres # 注意开头的 必须有!
# 创建一个 PostgreSQL 用户 `kong`,和上面创建的 Linux 用户 `kong` 对应。
$ create user kong with password '123456'; # 密码 '123456' 根据自己需要,进行随机生成~
# 创建一个 PostgreSQL 数据库 `kong`
$ create database kong owner kong;
# 将数据库 `kong` 授权给 PostgreSQL 用户 `kong`
$ grant all privileges on database kong to kong;
# 退出 PostgreSQL 控制台
$ q
新建 kong
数据库
③ PostgreSQL 有四种身份认证方式:
“
- trust:凡是连接到服务器的,都是可信任的。只需要提供 PostgreSQL 用户名,可以没有对应的操作系统同名用户。
- password 和 md5:对于远程访问,需要提供 PostgreSQL 用户名和密码。对于本地连接,提供 PostgreSQL 用户名密码之外,还需要有操作系统访问权(用操作系统同名用户验证)。password 和 md5 的区别,就是远程访问时传输的密码是否用 md5 加密。
- ident:对于远程访问,从 ident 服务器获得客户端操作系统用户名,然后把操作系统作为数据库用户名进行登录对于本地连接,实际上使用了 peer。
- peer:对于本地访问,通过客户端操作系统内核来获取当前系统登录的用户名,并作为 PostgreSQL 用户名进行登录。
在 /var/lib/pgsql/12/data/pg_hba.conf
文件中,PostgreSQL 可以看到目前的配置情况。如下图所示:
/var/lib/pgsql/12/data/pg_hba.conf
配置文件(默认)
默认配置下,我们无法在本地或者远程使用 PostgreSQL 用户名和密码直接连接,因为本地使用 peer 认证方式,远程使用 ident 认证方式。解决方法比较简单,将本地和远程的认证方式修改成 trust 或者 password 即可。
下面,我们修改 /var/lib/pgsql/12/data/pg_hba.conf
文件,注释掉所有默认配置,并添加一条 host all all 0.0.0.0/0 trust
默认,无论远程还是本地访问,任何 PostgreSQL 用户和数据库,都使用 trust 认证方式。最终如下图所示:
/var/lib/pgsql/12/data/pg_hba.conf
配置文件(修改)
“友情提示:线上环境,考虑到安全性,建议使用相对细粒度的配置。例如说,将
0.0.0.0/0
修改成指定的内网网段。
修改完成后,执行 sudo systemctl restart postgresql-12
命令,重启 PostgreSQL 数据库。重启完成后,执行 psql -U kong -d kong -h 127.0.0.1 -p 5432
命令,使用 PostgreSQL 用户名 kong
连接 PostgreSQL 数据库 kong
,又因为是 trust
认证方式,所以无需附带密码。
④ 默认配置下,PostgreSQL 只允许本地连接,所以我们需要修改 /var/lib/pgsql/12/data/postgresql.conf
文件,添加 listen_address
配置项为 *
,允许远程连接。如下图所示:
/var/lib/pgsql/12/data/postgresql.conf
配置文件(修改)
修改完成后,执行 sudo systemctl restart postgresql-12
命令,重启 PostgreSQL 数据库。重启完成后,使用 Navicat 了解 PostgreSQL 数据库,如下图所示:
Navicat 连接 PostgreSQL 数据库
2.2 安装 Kong
《Kong 文档 —— CentOS 安装》,进行 CentOS 系统下的 Kong 的安装。
2.2.1 安装
① 浏览器打开 http://docs.konghq.com/install/aws-linux/ 地址,邮件下载 Kong 的 RPM 包。如下图所示:
Kong RPM 包下载
然后,执行 wget
命令,进行 Kong 的 RPM 包的下载。操作命令如下:
$ wget -O "kong.rpm" https://bintray.com/kong/kong-rpm/download_file?file_path=amazonlinux/amazonlinux/kong-2.0.4.aws.amd64.rpm
- 其中
-O "kong.rpm"
代表下载文件的命名。 - 最后一串 URL 代表下载文件的地址,
② 执行 yum install kong.rpm --nogpgcheck
命令,进行 Kong 的安装。
2.2.2 配置
① Kong 的默认配置文件是 /etc/kong/kong.conf.default
,使用 cp /etc/kong/kong.conf.default /etc/kong/kong.conf
命令,复制一份新的配置文件。
复制完成后,我们修改 /etc/kong/kong.conf
配置文件,设置使用 PostgreSQL 数据库。如下图所示:
/etc/kong/kong.conf
配置文件
② 执行 kong migrations bootstrap -c /etc/kong/kong.conf
命令,进行 Kong 的 PostgreSQL 数据库的表初始化。完成后,使用 Navicat 看到如下表:
初始化 PostgreSQL 表
③ 执行 kong start -c /etc/kong/kong.conf
命令,执行 Kong 的启动。启动成功时,会看到 Kong started
日志。
默认情况下,Kong 绑定 4 个端口:
- Proxy 8000:接收客户端的 HTTP 请求,并转发到后端的 Upstream。
- Proxy 8443:接收客户端的 HTTPS 请求,并转发到后端的 Upstream。
- Admin 8001:接收管理员的 HTTP 请求,进行 Kong 的管理。
- Admin 8444:接收管理员的 HTTPS 请求,进行 Kong 的管理。
简单测试如下:
代码语言:javascript复制# 请求 Proxy 端口
$ curl http://127.0.0.1:8000
{"message":"no Route matched with those values"}
# 因为我们暂时没配置 Kong 路由。
# 请求 Admin 端口
$ curl http://127.0.0.1:8001
{"plugins":{"enabled_in_cluster":[],"available_on_server":{... // 省略
# 注意,考虑到安全性,Admin 端口只允许本机访问。
3. Kong 控制台
Kong 分成免费版和企业版,毕竟都要吃饭的。免费版本的 Kong 是不提供 Kong 的控制台,只能通过 Kong Admin API 进行 Kong 的维护和管理,显然非常不方便。所幸开源社区提供了两个做的不错的 Kong 控制台项目:
- Kong Dashboard,已经有 15 个月左右未维护,不支持 Kong 2.x 版本。
- Konga,更新频繁,支持 Kong 2.X 版本。
因此,现在一般采用 Konga 作为 Kong 的控制台。界面如下图所示:
Konga 界面
- 基于 Kong Admin API 管理所有 Kong 的对象。
- 支持从数据库、文件、API 等远程数据源导入 Consumer。
- 管理多个 Kong 界面。
- 备份,恢复,通过快照迁移 Kong 节点。
- 通过健康检查监控 Kong 节点和 API 状态。
- 支持 Email 和 Slack 消息通知方式。
- 支持多用户,可以设置不同的权限。
- 支持 MySQL、PostgreSQL、MongoDB 数据库。
下面,我们来一起进行 Konga 的安装与学习。
“友情提示:如果胖友会使用 Docker 的话,安装起来会比较便捷,可参考如下文章:
- 《Kong 与 Konga 之 Docker 部署》
- 《Konga 文档 —— Production Docker Image》
3.1 安装 NodeJS 环境
因为 Konga 是基于 NodeJS 开发的项目,所以需要安装 NodeJS 相关的环境。执行命令如下:
代码语言:javascript复制“Node 的安装,可参考 https://github.com/nodesource/distributions 仓库。
# 安装 NodeJS 14.x 和 NPM
$ curl -sL https://rpm.nodesource.com/setup_12.x | bash -
$ yum install nodejs npm -y
# 打印版本
$ node --version
v12.17.0
$ npm --version
6.14.5
# 安装 gulp、bower、sails
$ npm install -g gulp
$ npm install -g bower
$ npm install -g sails
“
- NodeJS:运行在服务端的 JavaScript。
- npm:npm 是 JavaScript 世界的包管理工具,并且是 NodeJS 平台的默认包管理工具。通过 npm 可以安装、共享、分发代码,管理项目依赖关系。
- gulp:一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务。
- bower:一个针对Web开发的包管理器。该工具主要用来帮助用户轻松安装 CSS、JavaScript、图像等相关包,并管理这些包之间的依赖。
- sails:NodeJS 的 MVC 框架。
3.2 安装 Konga
① 克隆 Konga 的源码,并下载 NodeJS 相关依赖包,并进行操作命令如下:
代码语言:javascript复制# 安装 Git,已安装可忽略
$ yum install git
$ git clone https://github.com/pantsel/konga.git
# 下载 NodeJS 相关依赖包
$ cd kongga
$ npm i
# 解决 bower 相关依赖包
$ npm run bower-deps
目前 Konga 支持使用 MySQL、PostgreSQL、SQLServer、MongoDB 四种数据库。下面,我们以 PostgreSQL 作为 Konga 的数据库举例子。
② 创建 Konga 的 PostgreSQL 数据库 konga
,命令行操作如下:
# 创建一个 Linux 用户 `konga`
$ adduser konga
# 进入 PostgreSQL 控制台
# 因为我们切换了 PostgreSQL 的认证方式为 trust 方式,所以可以这样连接
$ psql -U postgres -h 127.0.0.1 -p 5432
# 创建一个 PostgreSQL 用户 `konga`,和上面创建的 Linux 用户 `konga` 对应。
$ create user konga with password '123456'; # 密码 '123456' 根据自己需要,进行随机生成~
# 创建一个 PostgreSQL 数据库 `konga`
$ create database konga owner konga;
# 将数据库 `konga` 授权给 PostgreSQL 用户 `konga`
$ grant all privileges on database konga to konga;
# 退出 PostgreSQL 控制台
$ q
新建 konga
数据库
“友情提示:Konga 暂时不支持 12 版本的 PostgreSQL,所以下面艿艿卒了,只是“演示”整个过程。 建议使用 9.x 版本的 PostgreSQL 哈!
③ 执行 cp .env_example .env
命令,复制出 .env
配置文件,接入 PostgreSQL 作为数据库。配置内容如下:
PORT=1337
NODE_ENV=production
KONGA_HOOK_TIMEOUT=120000
DB_ADAPTER=postgres
DB_URI=postgresql://konga:123456@localhost:5432/konga
KONGA_LOG_LEVEL=warn
TOKEN_SECRET=some_secret_token
.env
配置文件
④ 执行如下命令,初始化 PostgreSQL 数据库:
代码语言:javascript复制$ node ./bin/konga.js prepare [--adapter postgres --uri postgresql://konga:123456@127.0.0.1:5432/konga]
初始化 PostgreSQL 数据库
“= = 因为艿艿安装的 PostgreSQL 版本过高,所以后面艿艿临时先使用 MySQL 作为 Konga 的数据库。下图是艿艿使用 MySQL 时候的操作:
MySQL 示例
最终 PostgreSQL 数据库 konga
的表如下图所示:
konga
表
⑤ 执行如下命令,启动 Konga 服务:
代码语言:javascript复制$ npm run production
> kongadmin@0.14.9 production /root/konga
> node --harmony app.js --prod
默认配置下,Konga 启动在 1337 端口。
代码语言:javascript复制⑥ 使用浏览器,访问 <http://127.0.0.1:1337/> 地址,进入 Konga 首页。因为 Konga 暂无**默认**管理员,所以自动跳转创建页面。如下图所示:
Konga 注册界面
按照自己的喜好,输入「账号/邮箱/密码」进行管理员的创建。创建完成后,重新访问 http://127.0.0.1:1337/ 地址,进入 Konga 登陆界面。如下图所示:
Konga 注册界面
输入「账号/密码」登陆 Konga。因为未配置 Kong 的 Admin URL 地址,所以进行添加。如下图所示:
Konga 初始化 Kong 界面
添加完 Admin URL 地址后,我们就可以在 Konga 界面中看到 Kong 的信息。如下图所示:
Kong 信息
至此,我们已经完成了 Konga 的安装,胖友可以自己点点 Konga 的界面,愉快的玩耍吧~
“旁白君:后续,我们会一边进行 Kong 的学习,一边演示在 Konga 中的展示。
4. 动态负载均衡
本小节,我们来实现对后端服务提供的 API 接口进行负载均衡。考虑到方便,艿艿在 https://github.com/YunaiV/SpringBoot-Labs 仓库提供了一个 Spring Boot 项目 lab-56-demo01
,如下图所示:
Spring Boot 项目
最终示例的效果,如下图所示:
项目效果
最终我们使用 Kong 实现负载均衡的效果等同于如下 Nginx 的配置:
代码语言:javascript复制upstream demo-upstream {
server localhost:18081 weight=100;
server localhost:18082 weight=50;
}
server {
listen 80;
location /demo-api/ {
proxy_pass http://demo-upstream;
}
}
下面,我们来通过 Kong Admin API 进行上述的负载均衡的配置。
4.1 创建 upstream 和 target
① 调用 Kong Admin API /upstreams
,创建名字为 demo-upstream
的 upstream:
$ curl -X POST http://127.0.0.1:8001/upstreams --data "name=demo-upstream"
Kong upstream
② 调用 Kong Admin API /upstreams/{upstream}/targets
,创建 Spring Boot 项目对应的 2 个 target:
代码语言:javascript复制“注意,
{upstream}
路径参数,为 upstream 的名字。
# 端口 18080 对应的 target
$ curl -X POST http://127.0.0.1:8001/upstreams/demo-upstream/targets --data "target=10.8.8.34:18080" --data "weight=100"
# 端口 28080 对应的 target
$ curl -X POST http://127.0.0.1:8001/upstreams/demo-upstream/targets --data "target=10.8.8.34:28080" --data "weight=50"
“友情提示:艿艿这里 Spring Boot 项目启动在 IP 为 10.8.8.34 的服务器上。
Kong target
③ 如上的配置,效果等同于如下 Nginx 的配置:
代码语言:javascript复制upstream demo-upstream {
server localhost:18081 weight=100;
server localhost:18082 weight=50;
}
4.2 创建 service 和 route
① 调用 Kong Admin API /services
,创建名字为 demo-service
的 service:
$ curl -X POST http://127.0.0.1:8001/services --data "name=demo-service" --data "host=demo-upstream"
host
参数,用于设置对应的 upstream 的名字。
Kong service
② 调用 Kong Admin API services/${service}/routes
,创建一个请求路径为 path
的 route:
代码语言:javascript复制“注意,
{service}
路径参数,为 upstream 的名字。
$ curl -X POST http://localhost:8001/services/demo-service/routes --data "name=demo-route" --data "paths[]=/demo-api"
Kong route
Kong route
③ 如上的配置,效果等同于如下 Nginx 的配置:
代码语言:javascript复制server {
listen 80;
location /demo-api/ {
proxy_pass http://demo-upstream;
}
}
4.3 简单测试
不断执行 curl http://127.0.0.1:8000/demo-api/demo/echo
命令,请求 Kong 网关来负载均衡转发到后端的 Spring Boot 项目,结果如下:
echo:18080
echo:18080
echo:28080
...
负载均衡请求到多个节点,符合预期~
4.4 简单小结
在上面,我们看到了 Kong 的 upstream、target、service、route 四个对象,一起来简单小节下:
service route upstream target
代码语言:javascript复制service 对应服务,可以直接指向一个 API 服务节点(host
参数设置为 ip port),也可以指定一个 upstream 实现负载均衡。简单来说,服务用于映射被转发的后端 API 的节点集合
在 Kong 中,还有 Consumer、Plugin、Tag、Certificate、Target 等等对象,胖友可以阅读《Kong 文档 —— Admin API》了解更多。
另外,胖友如果想用 Konga 通过图形界面来配置,可以参考阅读《Kong 配置 service 和 route 实现简单 API 代理》文章。
5. 限流限速
Kong 提供了 Rate Limiting 插件,实现对请求的限流功能,避免过大的请求量过大,将后端服务打挂。
Rate Limiting 支持秒/分/小时/日/月/年多种时间维度的限流,并且可以组合使用。例如说:限制每秒最多 100 次请求,并且每分钟最多 1000 次请求。
Rate Limiting 支持 consumer
、credential
、ip
三种基础维度的限流,默认为 consumer
。例如说:设置每个 IP 允许每秒请求的次数。计数的存储,支持使用 local
、cluster
、redis
三种方式进行存储,默认为 cluster
:
local
:存储在 Nginx 本地,实现单实例限流。cluster
:存储在 Cassandra 或 PostgreSQL 数据库,实现集群限流。redis
:存储在 Redis 数据库,实现集群限流。
Rate Limiting 采用的限流算法是计数器的方式,所以无法提供类似令牌桶算法的平滑限流能力。
“友情提示:Kong 企业版提供了 [https://docs.konghq.com/hub/kong-inc/rate-limiting-advanced/](Rate Limiting Advanced) 插件,提供平滑限流的功能,且性能更加优秀。 The Rate Limiting Advanced plugin for Kong Enterprise is a re-engineered version of the incredibly popular Kong Rate Limiting plugin, with greatly enhanced configuration options and performance.
下面,我们在「4. 动态负载均衡」小节的基础上,对名字为 demo-service
的 service 进行限流。
5.1 创建 Rate Limiting 插件
调用 Kong Admin API services/${service}/plugins
,创建 Rate Limiting 插件的配置:
$ curl -X POST http://127.0.0.1:8001/services/demo-service/plugins
--data "name=rate-limiting"
--data "config.second=1"
--data "config.limit_by=ip"
name
参数,设置为rate-limiting
表示使用 Rate Limiting 插件。config.second
参数,设置为 1 表示每秒允许 1 次请求。config.limit_by
参数,设置为ip
表示使用 IP 基础维度的限流。
Kong Rate Limiting 01
Kong Rate Limiting 02
“友情提示:Rate Limiting 插件还支持给 route、consumer 设置限流配置,胖友可以阅读《Kong 文档 —— Rate Limiting》学习。
5.2 简单测试
快速使用 curl http://127.0.0.1:8000/demo-api/demo/echo
命令 2 次,会被 Kong 限流,返回结果如下:
{"message":"API rate limit exceeded"}
6. JWT 身份验证
Kong 提供了 JWT 插件,实现使用 JWT 进行认证,保护后端服务的安全性。
可能有胖友不了解 JWT 认证方式,可以先阅读如下文章:
- 《JSON Web Token - 在Web应用间安全地传递信息》
- 《八幅漫画理解使用 JSON Web Token 设计单点登录系统》
下面,我们在「4. 动态负载均衡」小节的基础上,对名字为 demo-service
的 service 进行 JWT 身份认证。
6.1 创建 JWT 插件
① 调用 Kong Admin API services/${service}/plugins
,创建 JWT 插件的配置:
$ curl -X POST http://127.0.0.1:8001/services/demo-service/plugins
--data "name=jwt"
name
参数,设置为jwt
表示使用 JWT 插件。
Kong JWT 01
Kong JWT 02
② 使用 curl http://127.0.0.1:8000/demo-api/demo/echo
命令,会被 Kong 安全拦截。返回结果如下:
{"message":"Unauthorized"}
“友情提示:JWT 插件还支持给 route、consumer 设置 JWT 认证方式,胖友可以阅读《Kong 文档 —— JWT》学习。
6.2 创建用户
① 调用 Kong Admin API consumers
,创建一个 Consumer 消费者(用户):
$ curl -i -X POST http://localhost:8001/consumers/
--data "username=yunai"
username
参数,设置用户名为yunai
。
Kong Consumer 01
Kong Consumer 02
② 调用 Kong Admin API consumers/{username}/{plugin}
,生成该消费者的 JWT 信息:
代码语言:javascript复制“
{username}
路径参数,为 Consumer 的用户名。{plugin}
路径参数,为 Plugin 的插件名。
$ curl -i -X POST http://localhost:8001/consumers/yunai/jwt/
{
"rsa_public_key": null,
"created_at": 1590943621,
"consumer": {
"id": "8fa7e054-9cda-486f-b611-229bf7780969"
},
"id": "1af4ee95-f5fb-484c-97da-b5b205bd07c8",
"tags": null,
"key": "VbC63YmEg57fgVSLsKsrBHcVe9nu9XLX",
"secret": "xtgiCmCLtF7khq7SoAsrZDfVCQGHk5Pl",
"algorithm": "HS256"
}
- 注意
key
和secret
的结果,稍后会使用到。
使用 JWT Debugger 功能,生成 JWT Token。示例如下图所示:
JWT Debugger 生成 Token
③ 重新访问 http://127.0.0.1:8000/demo-api/demo/echo 地址,带上刚生成的 JWT Token。操作命令如下:
代码语言:javascript复制$ curl http://127.0.0.1:8000/demo-api/demo/echo
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJWYkM2M1ltRWc1N2ZnVlNMc0tzckJIY1ZlOW51OVhMWCJ9.rbWcXb-c1AwA3haiMWKStOcTCjkgVw1gmYMFeV8In6w"
echo:18080
成功!美滋滋~