1. 概述
在授权控制
, 流量控制
, 后端路由
,错误码映射
插件中,支持用户从当前的请求
、应答
或系统上下文
中获取参数,并使用自定义的条件表达式对参数进行判断,本文描述参数的定义方法与条件表达式的书写方法。
2. 参数的定义
2.1. 定义方式
在使用条件表达式前,需要先在parameters
字段中将所有需要在条件表达式中需要使用的参数进行显式定义,参考下面的例子:
---
parameters:
method: "Method"
appId: "System:CaAppId"
action: "Query:action"
userId: "Token:UserId"
parameters
字段类型是字符串类型的键值对,key
和value
的定义规范为
key
表示将来在条件表达式中使用的变量名,变量名的规则为[a-zA-Z_][a-zA-Z0-9]+
, 唯一value
表示参数艘在的位置,使用{location}
或{location}:{name}
的方式进行定义,请参考如下的例子:-
location
表示参数所在的位置,参考下一节的详细描述name
表示参数的名称,用于在所在位置中定位参数,比如Query:q1
表示请求的QueryString中名字为q1的第一个值
2.1. 参数的支持位置
在使用条件表达式前,我们需要先定义参与条件表达式计算的参数,目前API网关支持在插件中直接使用如下位置的参数
位置名称 |
适用范围 |
说明 |
---|---|---|
Method |
请求 |
HTTP请求方法(大写),如:
,
… |
Path |
请求 |
HTTP完整请求路径,如:
|
StatusCode |
应答 |
后端的HTTP应答码,如:
,
|
ErrorCode |
应答 |
|
Header |
请求/应答 |
使用
获取名字为
的HTTP头的第一个值 |
Query |
请求 |
使用
获取QueryString中名字为
的第一个值 |
Form |
请求 |
使用
获取请求Form中名字为
的第一个值 |
Host |
请求 |
使用
获取匹配到的泛域名模板参数 |
Parameter |
请求 |
使用
获取用户API自定义参数中名字为
的第一个值 |
BodyJsonField |
应答* |
使用
以
方式获取请求/应答包体中的JSON字段值 |
System |
请求/应答 |
使用
获取名字为
的
值 |
Token |
请求/应答 |
当处于
,
授权场景时,使用
获取token中名字为
的值 |
取值规则的说明
- 插件访问控制,流量控制,后端路由发生在请求阶段,插件仅支持适用范围为请求的参数位置:
Method
,Path
,Header
,Query
,Form
,Parameter
,System
,Token
- 插件错误码映射发生在应答阶段,插件仅支持适用范围为应答的参数位置:
StatusCode
,ErrorCode
,Header
,BodyJsonField
,System
,Token
Method
,Path
,StatusCode
,ErrorCode
这几个位置仅提供Location即可,不需要NameHeader
位置的参数,当用于请求阶段的插件时,读取来自客户端请求中的Header; 当用于应答阶段的插件时,读取来自后端应答中的HeaderParameter
位置的参数,仅用于请求阶段的插件,查找API定义中同名的参数,使用参数名
而非后端参数名
查找,当参数不存在时返回为null
Host
位置的参数,仅支持在泛域名参数提取,参考泛域名使用说明, 完整的Host请使用System:CaDomain
读取系统参数Path
返回为完整的请求路径,如果需要Path
位置的参数,请使用Parameter
位置的参数BodyJsonField
位置的参数,目前仅支持在错误码映射中使用,使用JSONPath
方式读取应答json包体的值,参考2.4. JSONPath使用说明Token
当配置了JWT授权或OAuth2插件时,使用Token:{CliamName}
可以读取在插件定义的值,参考对应插件的文档
2.3. JSONPath使用说明
用于BodyJsonField
位置,目前仅用于错误码映射插件,用于从后端返回的json
包体中提取json
中的字段,关于JSONPath的详细规范说明,请参考JSONPath介绍文档。
例子:使用
code:"BodyJsonField:$.result_code"
可以从如下的包体中得到
result_code
的值,对于如下的包体,可以解析到
code
:
ok
{ "result_code": "ok", "message": ... }
2.4. 系统参数列表
参数名称 |
参数含义 |
取值列表 |
---|---|---|
CaClientIp |
请求来源客户端IP |
如:
,
|
CaDomain |
请求的完整域名(Host头) |
如:
|
CaAppId |
请求的 APP 的 ID |
如:
|
CaAppKey* |
请求的 APP 的 Key |
如:
|
CaRequestId |
网关生成的唯一请求Id |
:
|
CaApiName |
API 名称 |
如:
|
CaHttpSchema |
调用协议 |
取值范围:
,
,
|
CaClientUa |
客户端的UserAgent头 |
透传客户端上传的值 |
CaCloudMarketInstanceId |
云市场购买关系Id |
云市场 |
CaMarketExpriencePlan |
是否开通云市场体验计划 |
开通:
, 未开通:
|
3. 条件表达式
条件表达式可在插件或其他场景中使用,用于在需要的场景中执行灵活的条件判断
3.1. 基本语法
- 条件表达式与SQL表达式类似,比如:
$A > 100 and '$B = 'B'
- 表达式的基本为
{参数} {操作符} {参数}
格式,如:$A > 100
参数支持变量参数
或常量参数
变量参数
以$
开头,用于引用在上下文中定义好的参数,例如:parameters
中定义了q1:"Query:q1"
的参数,在表达式中可以使用变量$q1
,这个变量的值为当前请求中名为q1
的Query参数的值常量参数
支持字符串
、数字
、布尔类型
,如"Hello"
,'foo'
,100
,-1
,0.1
,true
,请参考3.2. 参数类型与判断规则- 支持以下
操作符
: -
=
,==
: 等于判断<>
,!=
: 不等于判断>
,>=
,<
,<=
: 比较判断like
,!like
: 相似判断,在字符串头尾的%
可用于判断字符串相似,如$Query like 'Prefix%'
in_cidr
,
!in_cidr
: 判断IP地址的掩码,例如:
$ClientIp in_cidr '47.89.0.0/24'
- 可使用
null
来判断参数是否为空,如:$A == null
或$A != null
- 可以使用
and
,or
,xor
来组合连接不同的表达式,默认连接顺序为从右到左 - 可以用小括号
(
,)
来指定条件的优先级 - 使用
!(
,)
可以对括起来的表达式执行取反操作,如:!(1=1)
结果为false
- 系统内置了一些函数,用于一些特殊场景的判断
-
Random()
: 产生一个0-1
的浮点类型参数,用于蓝绿发布等一些需要随机的场合Timestamp()
: 返回以毫秒计数的Unix时间戳
TimeOfDay()
: 按GMT
时区,返回当前时间到当日零点的毫秒数
3.2. 参数类型与判断规则
表达式中支持以下类型
STRING
: 字符串类型,支持单引号或双引号,如:"Hello"
,'Hello'
NUMBER
: 整数或浮点数类型,如:1001
,-1
,0.1
,-100.0
BOOLEAN
: 布尔类型,如:true
、false
对于
等于
,不等于
,比较
操作符,不同类型的判断依据为STRING
: 使用字符串顺序执行判断,例如如:-
'123' > '1000'
结果为true'A123' > 'A120'
结果为true'' < 'a'
结果为true
NUMBER
: 使用数字大小进行判断-
123 > 1000
结果为false100.0 == 100
结果为true
BOOLEAN
: 布尔值的判断依据为:true
大于false
-
true == true
结果为truefalse == false
结果为truetrue > false
结果为true
对于
等于
,不等于
,比较
操作符,如果左右两侧的参数类型不一致,参考以下的判断依据:STRING
-
NUMBER
: 如果左值能转换为NUMBER
类型,则按照数字大小判断,否则按照字符串大小判断,例如:'100' = 100.0
结果为true'-100' > 0
结果为false
STRING
-
BOOLEAN
: 当左值能够转换为BOOLEAN
类型时(忽略大小写等于true
或false
是),按照BOOLEAN
类型判断,否则除了!=
判断外,其余的判断结果均为false
,参考如下例子:'True' = true
结果为true'False' = false
结果为true'bad' = false
结果为false'bad' != false
结果为true,对于左值非true
或false
的场景,除了!=
操作符结果为true
,其余结果均为false
'bad' != true
结果为true'0' > false
结果为false'0' <= false
结果为false
NUMBER
-
BOOLEAN
: 永远返回false
,例如
null
值可用于字段是否为空的判断,对于等于
,不等于
,比较
操作符,判断依据为- 当参数
$A
为空时,$A == null
结果为true,$A != null
结果为false - 空字符串
''
不等于null
时:'' == null
结果为false
,'' == ''
结果为true
- 当用于
比较
操作符时,任意一测值为null
,则结果为false
- 当参数
like
,!like
操作符,可用于字符串前缀、后缀、包含的判断,判断依据为- 表达式仅支持右值为
STRING
常量的写法,如$Path like '/users/%'
- 右值两端的
'%'
字符可用于支持前缀、后缀、与包含判断,如 -
- 前缀判断
$Path like '/users/%'
,$Path !like '/admin/%'
- 后缀判断
$q1 like '%search'
,$q1 !like '%.do'
, - 包含判断
$ErrorCode like '%400%'
,$ErrorCode !like '%200%'
,
- 前缀判断
- 当左值为非
NUMBER
或BOOLEAN
类型时,会转换为STRING
格式后执行判断 - 当左值为空值
null
时,结果为false
- 表达式仅支持右值为
in_cidr
,!in_cidr
表达式,可用于IP地址段掩码的判断,判断依据为- 表达式仅支持右值为
STRING
常量且符合IPv4或IPv6 CIDR格式的写法,如: -
$ClientIP in_cidr '10.0.0.0/8'
$ClientIP !in_cidr '0:0:0:0:0:FFFF::/96'
- 当左值类型为
STRING
类型时,会作为IPv4地址后进行判断 - 当左值类型为
NUMBER
,BOOLEAN
或为空时,结果为false
System:CaClientIp
参数会返回客户端的IP地址,一般使用这种方式执行判断
- 表达式仅支持右值为
4. 使用案例
- 随机5%的几率为真:
Random() < 0.05
- 判断当前API请求的是测试环境:
parameters:
stage: "System:CaStage"
$CaStage = 'TEST'
- 自定义参数中的UserName是Admin且来源IP在
47.47.74.0/24
范围内
parameters:
UserName: "Token:UserName"
ClientIp: "System:CaClientIp"
$UserName = 'Admin' and $CaClientIp in_cidr '47.47.74.0/24'
- 当前请求的用户Id是1001,1098,2011中的一个,且使用HTTPS协议请求
parameters:
CaAppId: "System:CaAppId"
HttpSchema: "System:CaHttpSchema"
$CaHttpScheme = 'HTTPS' and ($CaAppId = 1001 or $CaAppId = 1098 or $CaAppId = 2011)`
- 当应答StatusCode=200,包体
json
包体存在result_code
且不为ok
时
parameters:
StatusCode: "StatusCode"
ResultCode: "BodyJsonField:$.result_code"
$StatusCode = 200 and ($ResultCode <> null and $ResultCode <> 'ok')
5. 使用限制
- 单个插件中的参数定义个数不超过16个
- 单个表达式的字符数不超过512个字符
- BodyJsonField对请求或应答应答包体的限制为16K Bytes, 超过限制后将不会生效
在文档使用中是否遇到以下问题
更多建议
匿名提交