APISIX网关PublicAPI与Jwt-auth用法
1. 背景信息
当前用户在 Apache APISIX 中开发自定义插件时,可以为插件定义一些 public API,比如在当前的 jwt-auth 插件中,它实现并提供了一个 /apisix/plugin/jwt/sign 接口用于签发 JWT,由于此接口不是通过 Admin API 添加的,因此无法像管理 Route 一样管理此类接口。
在实际应用场景中,提供的接口是面向内部调用的,而非开放在公网供任何人调用。为了应对这种场景,Apache APISIX 设计了 public-api 插件,它替换了功能有限且使用复杂的插件拦截器。通过这个插件,可以解决 public API 使用过程中的痛点,可以为 public API 设置自定义的 uri,可以配置任何类型的插件。
2. public-api
以 jwt-auth 插件的 /apisix/plugin/jwt/sign 接口为例,介绍 public-api 插件两种使用方法和一种场景示例。
在使用 public-api 插件之前,如果在插件开发中使用 _M.api() 注册了 public API 后,APISIX 会默认将它暴露出来,可以直接在 HTTP 端口调用这个 API。
现在,您需要手动创建一个路由,配置 public-api 插件,才可以将 API 转发至 public-api 插件中。
确认API是否被开放,可以通过下述命令请求 API 地址,通过返回结果可以看到 /apisix/plugin/jwt/sign 默认情况下并没有被暴露出来,是不可用的。
curl -XGET 'http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=k12_device'
{"error_msg":"404 Route Not Found"}
3. 使用public-api
前提条件:需要创建 Consumer 并开启 jwt-auth 插件,才可以执行以下步骤。
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/consumers' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-H 'Content-Type: application/json' \
-d '{
"username": "K12_Device",
"desc": "消费者为K12支付宝设备",
"plugins": {
"jwt-auth": {
"key": "k12_device",
"algorithm": "HS256"
}
}
}'
2.1 方法一:基础使用
- 设置路由:根据前提条件中的 Consumer 创建 Route,设置 uri 为 jwt-auth 插件中签发 JWT 的 API 地址,并在此 Route 中开启 public-api 插件。
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r1' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-H 'Content-Type: application/json' \
-d '{
"uri": "/apisix/plugin/jwt/sign",
"name": "getToken",
"desc": "public API r1路由获取jwt token",
"plugins": {"public-api": {}}
}'
- 测试示例:使用如下命令进行测试,如果您看到返回结果是一个 JWT 字符串,表示此 public API 已经可以使用。
curl -XGET 'http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=k12_device'
2.2 方法二:自定义路径
在使用 public-api 插件之前,用户想要修改一个 public API 对外开放的 uri,是比较困难的。使用 prometheus 插件的用户可以通过修改配置文件的方法自定义 exporter uri,但是对于其他 Apache APISIX 的插件,只能通过修改插件文件的方式来实现,而在生产环境中此操作是有困难且有风险的。
现在您可以使用 public-api 插件修改 public API 对外开放的 uri,具体操作示例如下。
- 设置路由,使用如下命令修改方法一中创建的 Route,并设置 uri=/gen_token,同时将原有的 uri 配置到 public-api 插件中的 uri 字段。
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r2' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-H 'Content-Type: application/json' \
-d '{
"uri": "/gen_token",
"name": "getToken",
"desc": "public API r2路由获取jwt token",
"plugins": {
"public-api": {"uri": "/apisix/plugin/jwt/sign"}
}
}'
- 测试示例:使用新 uri 可以正常访问 public API
curl -XGET 'http://127.0.0.1:9080/gen_token?key=k12_device'
使用旧 uri 无法访问 public API(记得将方法一中定义的routes删掉)。
curl -XGET 'http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=k12_device'