欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Kong自定义插件【request-keyword-param-check】 KongLuaHTTPRequest 

程序员文章站 2022-03-12 10:44:19
...
1、插件作用

校验请求参数间的关系,支持以下操作类型:
(1)mandatory,表示请求uri中是必须携带的参数
(2)contain,表示两个参数之间是否有包含关系,前者是否包含后者
(3)exist,表示所配置参数必须同时有值
(4)begin,表示请求参数值是否以某个指定值开头
(5)end,表示请求参数值是否以某个指定值结尾
(6)firm,表示请求参数是否为指定的值

2、核心代码

local function decideUriExists(uri_key,uri_value,uri_param_tab,uri_relation_tab)
  local exists = true

  local args = ngx.req.get_uri_args()
  local http_uri_key_value = args[uri_key]
  if (http_uri_key_value ~= nil)  and  (string.lower(uri_value) == string.lower(http_uri_key_value)) then
    -- Nothing to do
  else
     return exists
  end 
  
  for i = 1, #uri_param_tab do
    local local_uri_param = uri_param_tab[i]
    local local_uri_relation = uri_relation_tab[i]
    local sub_uri_param_tab = setmetatable(pl_stringx.split(local_uri_param, ";"), nil)
    -- according to this parameter to decide if condition true or false
    local skip_flag = false 
    -- process different logic operation according to relation
    -- relation=mandatory
    if ('mandatory' == local_uri_relation) then
      skip_flag = true
      for j = 1, #sub_uri_param_tab do
        local local_uri_key=sub_uri_param_tab[j]
        local http_uri_arg_value = args[local_uri_key]
        if (http_uri_arg_value == nil or http_uri_arg_value == "") then
          exists = false
          break
        end
      end
    end
    -- whether to skip the outer circle logic
    if (not exists) then
    break
    end
    -- relation=contain,only compare two uri key 
    if (not skip_flag and 'contain' == local_uri_relation) then
      skip_flag = true
      local parent_key_value = args[sub_uri_param_tab[1]]
      local child_key_value = args[sub_uri_param_tab[2]]
      local idx_end = nil
      if (parent_key_value == nil or parent_key_value == "" or child_key_value == nil or child_key_value == "") then
         exists = false
         break
      else
        _,idx_end = string.find(string.lower(parent_key_value),string.lower(child_key_value))
      end
      if (idx_end ~= nil  and idx_end >= 1) then
        -- Nothing to do
      else
        exists = false
        break
      end
    end
   -- relationship=exist,only compare two uri key
    if (not skip_flag and 'exist' == local_uri_relation) then
      skip_flag = true
      local parent_key_value = args[sub_uri_param_tab[1]]
      local child_key_value = args[sub_uri_param_tab[2]]
      if ((parent_key_value ~= nil and parent_key_value ~= "" and child_key_value ~= nil and child_key_value == "") or (parent_key_value ~= nil and parent_key_value == "" and child_key_value ~= nil and child_key_value ~="")) then
        exists = false
        break
      end
    end
   -- relationship=begin,only compare two uri key
   if (not skip_flag and 'begin' == local_uri_relation) then
      skip_flag = true
      local parent_key_value = args[sub_uri_param_tab[1]]
      local child_value = sub_uri_param_tab[2]
      local idx_begin = nil
      if (parent_key_value == nil or parent_key_value == "") then
         exists = false
         break
      else
        idx_begin,_ = string.find(string.lower(parent_key_value),string.lower(child_value))
      end
      if (idx_begin ~= nil  and idx_begin == 1) then
      else
        exists = false
        break
      end
   end
   -- relationship=end,only compare two uri key
   if (not skip_flag and 'end' == local_uri_relation) then
      skip_flag = true
      local parent_key_value = args[sub_uri_param_tab[1]]
      local child_value = sub_uri_param_tab[2]
      local idx_end = nil
      if (parent_key_value == nil or parent_key_value == "") then
         exists = false
         break
      else
        _,idx_end = string.find(string.lower(parent_key_value),string.lower(child_value))
      end
      if (idx_end ~= nil  and idx_end == string.len(parent_key_value)) then
      else
        exists = false
        break
      end
   end
   -- relationship=firm,only compare two uri key
   if (not skip_flag and 'firm' == local_uri_relation) then
      skip_flag = true
      local counter = 0
      for j = 1, #sub_uri_param_tab do
        local sub_key_and_value_tab = setmetatable(pl_stringx.split(sub_uri_param_tab[j], "="), nil)
        local http_uri_arg_value = args[sub_key_and_value_tab[1]]
        if (http_uri_arg_value ~= nil and http_uri_arg_value ~= "" and sub_key_and_value_tab[2] ~= nil and sub_key_and_value_tab[2] ~= "" and sub_key_and_value_tab[2] == http_uri_arg_value) then
        counter = counter + 1
        end
      end
     if (counter == 1) then
      exists = false
      break
     end
   end
   -- for end location

  end

  return exists
end


3、配置使用
(1)多个分组逻辑间通过英文逗号(,)隔开,同一分组参数间通过英文分号(;)隔开
(2)注意多个分组逻辑间可以使用相同的操作符;
(3)示例如下:
uri_relation_set=>mandatory,contain,exist,firm,begin,end
uri_key_group_set=>key_x;key_y;key_z,key_a;key_b,key_m;key_n,key_d=d1;key_e=e1;key_f=f1,key_w;part_value_w,key_o;part_value_o

【温馨提示】
如果您觉得满意,可以选择支持下,您的支持是我最大的动力:

Kong自定义插件【request-keyword-param-check】
            
    
    
        KongLuaHTTPRequest