初探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的端口不应该暴露出来,只该在内部调用,有兴趣可以看看konga和kong-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次才返回错误



待更新补充~

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

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

友情链接更多精彩内容