初探Kong实现API网关鉴权(OAuth2-Client Credentials模式)与调用频率限制(Rate Limiting)

        由于最近项目中需要搭建一个网关,在大佬的建议和自己调研下,最终使用了Kong。Kong是一款可扩展性和灵活性都很高的开源API网关,可以通过添加Kong节点水平扩展服务,可以通过Lua编写的插件扩展已有功能(官方已经提供了很多实用的插件),本文介绍的就是通过添加OAuth2和Rate Limiting插件实现API网关鉴权与调用频率限制,更多丰富的功能参考官方文档
        写这篇文章的原因是由于在搭建网关过程中遇到了些问题,解决问题时发现Kong的旧版本与新版本差异很大,而国内外网上的例子大多是基于旧版本的或者内容比较简单,gitHub的Issue中也有很多基于旧版本的回答无法用来参考,并且官方文档中有些地方对于新手比较容易产生误解,所以想写篇简单清晰的例子提供下参考,有什么不对的地方也请指正!


注意事项

  • Kong:本文是基于1.4版本的,Kong新旧版本差异有点大,所以过一阵可能也不适用了......
  • OAuth2:新版本插件要求必须使用HTTPS请求获取token,所以必须要有域名与SSL证书(个人是使用Let’s Encrypt申请的免费证书,不过好像也有基于IP的SSL证书,没实践过,这里不做更多介绍),旧版本没有硬性要求所以网上有些例子用的HTTP请求也可以获取到token。

Kong部署

本文是介绍部署在docker中的例子,可以在DockerHub中查看更详细的介绍,更多部署方式参考官方文档

1.创建一个Docker网络,以使容器能够发现彼此并进行通信

docker network create kong-net

2.创建Postgres数据库(也可以使用Cassandra,有个坑是用Postgres12会报错,11.5则不会)

docker run -d --name kong-database \
    -p 5432:5432 \
    -e "POSTGRES_USER=kong" \
    -e "POSTGRES_DB=kong" \
    postgres:9.6

3.准备数据库

docker run --rm \
    --link kong-database:kong-database \
    -e "KONG_DATABASE=postgres" \
    -e "KONG_PG_HOST=kong-database" \
    kong kong migrations bootstrap

4.运行一个Kong容器

  • 8000:监听来自客户端的HTTP请求,匹配路由后转发请求到具体的service上
  • 8443:监听来自客户端的HTTPS请求,匹配路由后转发请求到具体的service上
  • 8001:Kong的Admin API的HTTP接口,用于管理Kong平台,例如服务于路由的注册、插件的添加与配置
  • 8444:Kong的Admin API的HTTPS接口,用于管理Kong平台,例如服务于路由的注册、插件的添加与配置
docker run -d --name kong \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong

到这我们就搭好了个基本的单节点Kong网关,Kong只有企业版才提供GUI来管理API,gitHub上有开源的第三方仓库的GUI工具,不过只提供了些基本功能,生产环境也用不上,毕竟管理API的端口不应该暴露出来,只该在内部调用,有兴趣可以看看kongakong-dashboard(有个坑是使用konga时数据库主机地址要填公网IP)。


插件使用

搭好网关后我们就可以开始通过插件来扩展些我们需要的功能了,Kong的插件可以用于全局、服务、路由和消费者,同时在不同地方应用相同插件时是有优先级的,详情参考官方文档的Admin API下的Precedence,以下分别以全局插件(Rate Limiting例子)和服务插件(OAuth2例子)做介绍,OAuth2插件文档中还是有些地方比较容易让我这样的新手误解的......

OAuth2(Client Credentials模式)

官方插件文档官方接口文档

个人喜欢使用postman调用Admin API,域名已做处理,官方文档和网上不少例子是用curl命令调用的,看个人习惯吧,自行转换,反正最后都是通过代码调,以下是示例中用到的几个地址,自行替换为自己的地址

1.需要准备个测试用接口,当作一个service,在这我用项目的单点登录接口做演示,以下是正常调用返回结果,表示接口可用


2.通过接口上传所需的SSL证书,以便我们可以调用网关的HTTPS接口地址


3.创建一个service(通常是一个路由对应一个微服务,所以service只能指定一个path,如果一个微服务对应多个路由的话,则在定义route时需要设置strip_path为false,使匹配到的路由添加到上游服务的path中),当这个service被调用时,会将请求转发到http://xxx.53.189.48:3001/login/local

4.通过 http://xxxxx.org:8001/services/{上一步创建service时指定的name或返回的service id}/routes 创建一个route,创建完route后,我们就可以通过 http://xxxxx.org:8000/sso/login/local 调用service,默认配置下,当请求转发到上游服务时,会将这个route的path去掉,如例子中请求http://xxxxx.org:8000/sso/login/local转发到service后,会将/sso/login/local去掉,然后使用service的path调用具体服务,即http://xxx.53.189.48:3001/login/local;route的methods、paths和hosts都可以指定多个,从而可以通过多个url调用此服务。


5.为service添加一个OAuth2插件,再次调用http://xxxxx.org:8000/sso/login/local后就会返回错误,提示缺少token


6.当我们添加插件后,插件将会监听/oauth2/authorize,/oauth2/token,/oauth2_tokens,/oauth2_tokens/:token_id等路由,我们需要自己创建route映射到这些路由,这是容易误解的地方之一,之前一直直接调用https://xxxxx.org:8443/oauth2/token期望返回token(这里要注意使用的是网关的HTTPS接口地址,而不再是Kong的Admin API的HTTP接口地址),但是一直提示"Not found"、"no Route matched with those values"等错误

7.创建一个consumer,consumer作为消费者通常与用户相关联,我们该为每个用户创建一个consumer


8.通过 http://xxxxx.org:8001/consumers/{上一步创建consumer后返回的id}/oauth2 为这个consumer创建一个应用,应用会返回client_secret与client_id用于申请token

9.调用第5步中创建route时指定的path,即https://xxxxx.org:8443/sso/oauth2/token,与上一步生成的client_secret与client_id申请token

10.然后在请求头中加入Authorization: Bearer {token},发现调用成功


Rate Limiting

官方插件文档官方接口文档

1.在全局添加插件Rate Limiting,指定每分钟限制调用一次



2.然后在一分钟内两次调用测试接口,返回错误"API rate limit exceeded",即表示限制成功



3.我们希望指定用户可以多次调用时,可以通过在consumer上添加相同插件,由于consumer上的插件优先级高于全局插件,所以指定的用户可以越过全局插件限制多次调用

4.再次调用测试接口发现一分钟内调用10次才返回错误



待更新补充~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容

  • Kong 是 Mashape 开源的高性能高可用 API 网关和 API 管理服务层。它基于 OpenResty ...
    meng_philip123阅读 8,989评论 0 6
  • 更新,现在有更强大的API网关,国产 Apache APISIX,可自行谷歌。 本文转载自选择Kong作为你的AP...
    tenlee阅读 3,631评论 0 9
  • 马路是被车压伤的,可是梅雨季时马路会出现大大小小的坑!
    研究说明书阅读 165评论 0 0
  • 于小小的闲窗下, 看檐角阳光倾泻而下, 看时光过客浅淡过往, 翻开一页页的人生, 看那些风花雪月,风华过往, 叹那...
    遇见季风阅读 185评论 0 2
  • 每天都能看到你 每天和你在一起 一起想办法 把工作做到最好 为什么要去想以后? 不需要纠结从前 只要此时此刻 我们...
    走过路过就好阅读 332评论 2 15