前情提要:由于公司业务需求,需要针对 Kong 自定义插件,而 Kong 的插件主要是 Lua 语言,公司的技术栈是 Python,所以升级了 Kong 版本到 3.1。Kong3.1支持使用 Python 语言的插件,从此走上了踏坑填坑之路。(因为官方文档写的模棱两可,给的示例也不是很全面,所以升级版本和写插件过程很曲折)
# add below section to allow this plugin optionally be running in a dedicated process if __name__ == "__main__": # 启动服务 from kong_pdk.cli import start_dedicated_server
# add below section to allow this plugin optionally be running in a dedicated process if __name__ == "__main__": from kong_pdk.cli import start_dedicated_server
# 执行查询命令 cur.execute(f"select uuid, authentication from customer where certificate = '{client_certificate_id}'") rows = cur.fetchall() for row in rows: customer_uuid = row[0] customer_authentication = row[1] client_certificate_key = customer_authentication["client_key"] old_hash_data = f"{client_certificate_id}|{client_certificate_key}|{client_request_time}" new_hash_data = hashlib.sha256(old_hash_data.encode("utf-8")).hexdigest() if new_hash_data != client_request_signature: kong.response.error(403, "Access Forbidden") kong.service.request.add_header(f"X-Customer-Id", f"{customer_uuid}") except Exception as ex: kong.response.error(403, "Access Forbidden")
# add below section to allow this plugin optionally be running in a dedicated process if __name__ == "__main__": from kong_pdk.cli import start_dedicated_server
#pluginserver_names = # Comma-separated list of names for pluginserver # processes. The actual names are used for # log messages and to relate the actual settings.
#pluginserver_XXX_socket = <prefix>/<XXX>.socket # Path to the unix socket # used by the <XXX> pluginserver. #pluginserver_XXX_start_cmd = /usr/local/bin/<XXX> # Full command (including # any needed arguments) to # start the <XXX> pluginserver #pluginserver_XXX_query_cmd = /usr/local/bin/query_<XXX> # Full command to "query" the # <XXX> pluginserver. Should # produce a JSON with the # dump info of all plugins it # manages
for i, name inipairs(config.pluginserver_names) do name = name:lower() kong.log.debug("search config for pluginserver named: ", name) local env_prefix = "pluginserver_" .. name:gsub("-", "_") _servers[i] = { name = name, socket = config[env_prefix .. "_socket"] or"/usr/local/kong/" .. name .. ".socket", start_command = config[env_prefix .. "_start_cmd"] or ifexists("/usr/local/bin/"..name), query_command = config[env_prefix .. "_query_cmd"] or ifexists("/usr/local/bin/query_"..name), } end end
kong | 2023/02/06 16:40:11 [debug] 1#0: [kong] process.lua:66 search config for pluginserver named: customer_verification # 代表已经从配置文件中获取到插件配置 kong | 2023/02/06 16:40:11 [debug] 1#0: [kong] mp_rpc.lua:33 mp_rpc.new: /usr/local/kong/customer_verification.sock # 该文件可自定义,或者由 kong 自己在默认路径中生成 kong | 2023/02/06 16:40:11 [debug] 1#0: [lua] plugins.lua:284: load_plugin(): Loading plugin: customer_verification # 代表创建已经被 kong 识别到并加载 kong | 2023/02/06 16:40:12 [info] 1129#0: *602 [customer_verification:1133] WARN - [16:40:12] lua-style return values are used, this will be deprecated in the future; instead of returning (data, err) tuple, only data will be returned and err will be thrown as PDKException; please adjust your plugin to use the new python-style PDK API., context: ngx.timer kong | 2023/02/06 16:40:12 [info] 1129#0: *602 [customer_verification:1133] INFO - [16:40:12] server started at path /usr/local/kong/customer_verification.sock, context: ngx.timer # 代表插件服务器已经启动