有条件地禁用全局插件
全局插件默认适用于所有路由,这对于强制执行组织范围内的策略(如身份验证、日志记录或监控)非常有用。但是,在某些情况下,你可能希望为特定路由或服务禁用某些全局插件以满足业务或技术要求。
本指南将向你展示如何微调全局插件的执行,以便插件仅在需要的地方运行,而在不需要的地方被跳过。你将在全局启用 multi-auth,并禁用选定路由上的插件执行。
API7 Ingress Controller 目前不支持配置路由标签,而这正是完成本指南所必需的。
在条件中使用正则表达式匹配
在本节中,你将使用正则表达式匹配来基于路由标签有条件地跳过全局插件的执行。
与基于列表的匹配相比,复杂的正则表达式可能会产生更多的处理开销。
创建 Serverless 函数
创建一个 Serverless 函数,当路由包含标签时注册变量 api7_disable_global_rules。稍后将使用该变量的值来确定是否应禁用全局插件。
-
导航到你的网关组。
-
在左侧菜单栏中,点击 Plugin Settings 并添加一个新插件。
-
添加
serverless-pre-function插件。 -
应用以下配置:
functions:
- |-
return function(conf, ctx)
local core = require "apisix.core"
core.ctx.register_var("api7_disable_global_rules", function(ctx)
local route = ctx.matched_route and ctx.matched_route.value
if route and route.labels then
return route.labels.api7_disable_global_rules
end
return 1
end)
end
phase: rewrite
配置全局插件
配置一个带有 _meta.filter 的示例全局插件,使用正则表达式匹配有条件地确定是否应执行它。如果 api7_disable_global_rules 的值匹配插件名称,全局插件将被跳过。
-
导航到你的网关组。
-
在左侧菜单栏中,点击 Plugin Settings 并添加一个新插件。
-
添加
multi-auth插件。 -
应用以下配置:
{
"_meta": {
"filter": [
[
"api7_disable_global_rules",
"!",
"~~",
".*multi-auth.*"
]
]
},
"auth_plugins": [
{
"basic-auth": {}
},
{
"key-auth": {
"header": "apikey",
"hide_credentials": true,
"query": "apikey"
}
}
]
}
全局插件将跳过对其 api7_disable_global_rules 标签包含 multi-auth 的资源的执行。
配置路由
- 按照快速入门指南创建一个服务。在服务中,创建两个路由:
/ip和/get。 - 在
/get路由上配置一个标签api7_disable_global_rules,值为multi-auth。
创建消费者
- 按照管理消费者凭证创建两个消费者:
consumer1和consumer2。 - 为
consumer1配置 basic authentication(基本认证)凭证,使用consumer1作为用户名,consumer1_pwd作为密码。 - 为
consumer2配置 key authentication(密钥认证)凭证,使用consumer2_pwd作为密钥。
验证
发送一个没有任何凭证的请求到 /get 路由:
curl -i "http://127.0.0.1:9080/get"
由于 multi-auth 对该路由被禁用,你应该会收到 HTTP/1.1 200 OK 响应。
发送一个没有任何凭证的请求到 /ip 路由:
curl -i "http://127.0.0.1:9080/ip"
由于 multi-auth 对该路由生效,你应该会收到 HTTP/1.1 401 Unauthorized 响应。
发送两个请求到 /ip 路由,一个使用 basic authentication,另一个使用 key authentication:
curl -i "http://127.0.0.1:9080/anything" -u 'consumer1:consumer1_pwd'
curl -i "http://127.0.0.1:9080/anything" -H 'apikey: consumer2_pwd'
由于凭证有效,你应该会收到两个请求的 HTTP/1.1 200 OK 响应。
在条件中使用基于列表的匹配
在本节中,你将使用基于列表的匹配来基于路由标签有条件地跳过全局插件的执行。
创建 Serverless 函数
创建一个 Serverless 函数,当路由包含标签时注册变量 api7_disable_global_rules。标签可以包含一个或多个以逗号分隔的插件名称,这些名称将被拆分和修剪以形成一个列表。稍后将使用此列表来确定应禁用哪些全局插件。
-
导航到你的网关组。
-
在左侧菜单栏中,点击 Plugin Settings 并添加一个新插件。
-
添加
serverless-pre-function插件。 -
应用以下配置:
functions:
- >-
return function(conf, ctx)
local core = require "apisix.core"
core.ctx.register_var("api7_disable_global_rules", function(ctx)
local route = ctx.matched_route and ctx.matched_route.value
if route and route.labels then
local value = route.labels.api7_disable_global_rules
if value then
local disable_plugins = {}
for plugin_name in string.gmatch(value, "[^,]+") do
local trimmed_name = string.gsub(plugin_name, "^%s*(.-)%s*$", "%1")
if trimmed_name and trimmed_name ~= "" then
table.insert(disable_plugins, trimmed_name)
end
end
core.log.error("disable_plugins: ", core.json.encode(disable_plugins))
return disable_plugins
end
end
return 1
end)
end
phase: rewrite
配置全 局插件
配置一个带有 _meta.filter 的示例全局插件,使用基于列表的匹配有条件地确定是否应执行它。如果 api7_disable_global_rules 变量包含插件名称,全局插件将被跳过。
-
导航到你的网关组。
-
在左侧菜单栏中,点击 Plugin Settings 并添加一个新插件。
-
添加
multi-auth插件。 -
应用以下配置:
{
"_meta": {
"disable": false,
"filter": [
[
"api7_disable_global_rules",
"!",
"has",
"multi-auth"
]
]
},
"auth_plugins": [
{
"basic-auth": {}
},
{
"key-auth": {
"header": "apikey",
"hide_credentials": true,
"query": "apikey"
}
}
]
}
全局插件将跳过对其 api7_disable_global_rules 标签的禁用插件列表中包含 multi-auth 的资源的执行。