背景信息
以后用户在 Apache APISIX 中开发自定义插件时,能够为插件定义一些 API(下称 public API),比方在以后的 jwt-auth
插件中,它实现并提供了一个/apisix/plugin/jwt/sign
接口用于签发 JWT,因为此接口不是通过 Admin API 增加的,因而无奈像治理 Route 一样治理此类接口。
在理论利用场景中,提供的接口是面向外部调用的,而非凋谢在公网供任何人调用。为了应答这种场景,Apache APISIX 设计了 plugin-interceptors
(插件拦截器),通过此性能能够让 public API 利用局部插件并实现申请过滤,然而以后仅反对 ip-restriction
插件。
由上能够看出,Apache APISIX 对于 public API 的申请过滤能力是比拟弱的,所以不能应用 Apache APISIX 中其余插件实现简单的认证和受权能力。
因而,Apache APISIX 设计了 public-api
插件,它替换了性能无限且应用简单的插件拦截器。通过这个插件,能够解决 public API 应用过程中的痛点,您能够为 public API 设置自定义的 uri,能够配置任何类型的插件。下图展现了应用 public-api
前后的变动。
不反对在 Docs 外粘贴 block
初识 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=user-key'
{"error_msg":"404 Route Not Found"}
前提条件
您须要创立 Consumer 并开启 jwt-auth
插件,才能够应用 jwt-auth
插件。
示例中
jwt-auth
参数配置信息,请参考 jwt-auth。
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/consumers' \
-H 'X-API-KEY: $<api-key>' \
-H 'Content-Type: application/json' \
-d '{"username":"APISIX","plugins": {"jwt-auth": {"key":"user-key","algorithm":"HS256"}
}
}'
办法一:根底应用
-
设置路由
依据前提条件中的 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: <api-key>' \
-H 'Content-Type: application/json' \
-d'{"uri":"/apisix/plugin/jwt/sign","plugins": {"public-api": {}
}
}'
-
测试示例
应用如下命令进行测试,如果您看到返回后果是一个 JWT 字符串,示意此 public API 曾经能够应用。
curl -XGET 'http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key'
<header>.<payload>.<signature>
办法二:自定义门路
在应用 public-api
插件之前,用户想要批改一个 public API 对外开放的 uri,是比拟艰难的。应用 prometheus
插件的用户能够通过批改配置文件的办法自定义 exporter uri,然而对于其余 Apache APISIX 的插件,只能通过批改插件文件的形式来实现,而在生产环境中此操作是有艰难且有危险的。
当初您能够应用 public-api
插件批改 public API 对外开放的 uri,具体操作示例如下。
-
设置路由
应用如下命令批改办法一中创立的 Route,并设置 uri=/gen_token
,同时将原有的 uri 配置到 public-api
插件中的 uri 字段。
# 创立路由并开启 public-api 插件
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r1' \
-H 'X-API-KEY: <api-key>' \
-H 'Content-Type: application/json' \
-d '{"uri":"/gen_token","plugins": {"public-api": {"uri":"/apisix/plugin/jwt/sign"}
}
}'
-
测试示例
应用新地址能够失常拜访 public API。
curl -XGET 'http://127.0.0.1:9080/gen_token?key=user-key'
<header>.<payload>.<signature>
应用旧 uri 无法访问 public API。
curl -XGET 'http://127.0.0.1:9080/apisix/plugin/jwt/sign?key=user-key'
{"error_msg":"404 Route Not Found"}
场景示例:爱护路由
本节将介绍如何应用 public-api
插件解决 plugin-interceptors
插件所带来的业务痛点,即仅能应用繁多的 IP 限度插件。
以下步骤以 key-auth
插件为例,为您介绍如何应用 public-api
插件爱护 public API。
示例中
key-auth
配置信息,请参考 key-auth。
-
创立 Consumer
创立 Consumer,并配置 key-auth
密钥。
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/consumers' \
-H 'X-API-KEY: <api-key>' \
-H 'Content-Type: application/json' \
-d '{"username":"APISIX","plugins": {"key-auth": {"key":"test-apikey"}
}
}'
-
设置路由
批改办法二中创立的路由,并开启 key-auth
插件和 public-api
插件。
# 创立路由并开启 public-api 插件
curl -XPUT 'http://127.0.0.1:9080/apisix/admin/routes/r1' \
-H 'X-API-KEY: <api-key>' \
-H 'Content-Type: application/json' \
-d '{"uri":"/gen_token","plugins": {"public-api": {"uri":"/apisix/plugin/jwt/sign"},"key-auth": {}}
}'
-
测试示例
通过测试,当申请携带正确的 apikey
时,public API 能够失常响应,而没有携带 apikey
时,将返回 401
未认证的状态码。如果您测试的返回后果和示例状态统一,则证实您刚刚配置的 key-auth
插件曾经失效。
# with corrent apikey
curl -XGET 'http://127.0.0.1:9080/gen_token?key=user-key'
-H "apikey: test-apikey"
<header>.<payload>.<signature>
# without apikey
curl -i -XGET 'http://127.0.0.1:9080/gen_token?key=user-key'
HTTP/1.1 401 UNAUTHORIZED
原理详解
从上述示例中您能够看出,public-api
插件能够很好的解决用户在应用 public API 时的缺点。本节为您具体介绍实现原理。
总述
对于 public-api
的原理,能够应用一句话形容:public-api
插件将之前独自的 public API 路由匹配转移到插件外部,仅对开启插件的路由进行 public API 匹配。以下将从两个方面为您具体解释原理。
应用 public-api
插件之前
首先,您须要理解 Apache APISIX 在集成public api
之前是如何实现 public API 的性能的。
- 当 APISIX 启动时会加载自定义插件,并应用从 etcd 获取的 Route 配置构建 radixtree 路由器,它将负责依据申请信息匹配 Route 并调用正确的 handler 来转发申请。
- APISIX 将为自定义插件的 public API 与用户创立的 Route 别离创立不同的路由器(下文别离称为 public API 路由器和 Route 路由器)
- 当申请达到时,将先由 public API 路由器进行匹配,之后再由 Route 路由器进行匹配。它们是申请解决流程上齐全离开的两个局部。
无奈复制加载中的内容
依据此流程,如果您想将面向 Route 路由器的插件利用在 public API 路由器上,就须要手动保护一个插件列表,并在 public API 路由器匹配到之后手动执行插件函数。由此能够看出,这样的架构是简单且难以保护的,并且带来了许多问题,如应用简单(基于 plugin_metadata 的配置形式)、粗粒度配置(难以为一个插件中提供的多个 public API 执行不同的策略)等。
减少 public-api
插件之后
在咱们引入了 public-api
插件后,上述流程将会被简化,将原来先于 Route 路由匹配执行的 public API 路由匹配被转移到了插件中。
- 当申请达到时,APISIX 会间接执行 Route 路由匹配,当找到相应的路由后,将转发申请至插件中进行解决。
- 当一个 Route 开启了
public-api
插件时,将依据插件的配置调用指定的 public API 进行申请解决,不再执行申请的转发。而没有开启public-api
插件的 Route,将不会进行解决。
无奈复制加载中的内容
自定义插件提供的 public API 默认将不再裸露进去,而是由用户配置 Route 来决定以何种形式提供,能够自在的设置路由参数,如 uri
, host
, method
等,之后只须要为路由开启 public-api
插件即可。
因为 public-api
插件具备较低的优先级,它将在大部分插件执行完之后再执行,这样用户就能够为 Route 配置任意认证和安全类插件。
Apache APISIX 不再进行两阶段的 Route 路由匹配和执行不同的逻辑,所有归于 Route 路由匹配,申请解决的流程也被大大简化。
总结
须要留神,public-api
在被纳入正式版本公布之后,在 APISIX 的 HTTP 申请解决流程中,Apache APISIX 将不再进行 public API 的路由匹配,即默认不裸露插件中注册的 public API。您能够参考上述 public-api
插件的操作示例来更加灵便的应用 public API 的性能。
如果您曾经在之前的版本实现自定义插件的开发,降级版本后会对您的业务造成影响,请您降级前再次确认。
对于 public-api
插件的更多阐明和残缺配置信息,可参考 public-api。
Apache APISIX 我的项目目前正在开发其余插件以反对集成更多服务,如果您对此有趣味,您能够通过 GitHub Discussions 发动探讨,或通过邮件列表进行交换。