如何使用 Nginx 和 Lua 操作 POST 请求的 JSON 正文? [英] How can I manipulate the JSON body of a POST request using Nginx and Lua?

查看:45
本文介绍了如何使用 Nginx 和 Lua 操作 POST 请求的 JSON 正文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个概念验证来演示我们如何在我们的堆栈中实现 3scale.在一个例子中,我想要做一些 POST request 主体操作来创建一个 API 外观,将可能是遗留 API 格式的内容映射到新的内部格式.例如.改变类似

{ "foo" : "bar" , "deprecated" : true }

进入

{ "FOO" : "bar" }

content_by_luaLua 模块文档,看起来像适当的方法说

<块引用>

不要在同一位置使用此指令和其他内容处理程序指令.例如,该指令和 proxy_pass 指令不应用于相同的位置.

我的理解是 content_by_lua 是一个类似于 proxy_pass 的内容处理程序,每个位置只能使用其中一个.

我认为没有任何方法可以删除 proxy_pass,因为这是代理工作的基础,所以是否可以在单独的位置捕获请求,使用 content_by_luastrong>,然后传递到实现 proxy_pass 的位置,或者是否有不同的方法,例如 rewrite_by_lua 哪个更合适?

<小时>

如果它对其他人有帮助,我添加了以下函数(我的 Lua 的第一个位),它删除了 user_key 参数,该参数是 3scale 需要授权但如果转发对我们的 API 无效的参数:

function remove_user_key()ngx.req.read_body()-- 记录原始身体,以便我们稍后与新身体进行比较本地 oldbody = ngx.req.get_body_data()日志(旧体)-- 以表格形式获取 POST 参数本地参数 = ngx.req.get_post_args()-- 构建新的 JSON 字符串本地新人 = "{"对于 k,v 成对(参数)做-- 添加我们想要保留的所有参数如果 k ~= "user_key" 然后日志(添加"..k.."为..v)newbody = newbody..'"'..k..'":"'..v..'",'别的log("不添加user_key")结尾结尾--在关闭之前删除最后一个尾随逗号newbody = string.sub(newbody, 0, #newbody-1)新人 = 新人.."}"ngx.req.set_body_data(newbody)日志(新手)结尾如果 ngx.req.get_method() == "POST" 那么remove_user_key()结尾

解决方案

我会建议你使用 access_by_lua
在 nginx.conf

<前>地点/{#host和端口到fastcgi服务器default_type 文本/html;设置 $URL "http://$http_host$request_uri";access_by_lua_file/home/lua/cache.lua;proxy_pass http://$target;----------------

在 cache.lua 文件中,您可以执行以下操作:

<前>如果 ngx.req.get_method() == "POST" 那么-- 检查请求方法是否为POST-- 实现你的逻辑返回结尾

I am doing a proof of concept to demonstrate how we might implement 3scale in our stack. In one example I want to do some POST request body manipulation to create an API façade that maps what might be a legacy API format to a new internal one. Eg. change something like

{ "foo" : "bar" , "deprecated" : true }

into

{ "FOO" : "bar" }

The Lua module docs for content_by_lua, which seems like the appropriate method say

Do not use this directive and other content handler directives in the same location. For example, this directive and the proxy_pass directive should not be used in the same location.

My understanding is that the content_by_lua is a content handler like proxy_pass, only one of which can be used per location.

I don't think there's any way to remove proxy_pass as that's the basis of how the proxying works, so is it possible capture the request in a separate location, use content_by_lua, then pass to the location implementing proxy_pass or is there a different method like rewrite_by_lua which is more appropriate?


If it helps anyone else, I added the following function (my first bit of Lua) which removes the user_key parameter which 3scale requires for authorization but is invalid for our API if forwarded on:

function remove_user_key()
  ngx.req.read_body()
  -- log the original body so we can compare to the new one later
  local oldbody = ngx.req.get_body_data()
  log(oldbody)
  -- grab the POST parameters as a table
  local params = ngx.req.get_post_args()

  -- build up the new JSON string
  local newbody = "{"

   for k,v in pairs(params) do
     -- add all the params we want to keep
     if k ~= "user_key" then
        log("adding"..k.." as "..v)
        newbody = newbody..'"'..k..'":"'..v..'",'
     else 
        log("not adding user_key")
     end
   end
  --remove the last trailing comma before closing this off
  newbody = string.sub(newbody, 0, #newbody-1)
  newbody = newbody.."}"

  ngx.req.set_body_data(newbody)
  log(newbody)
end

if ngx.req.get_method() == "POST" then
  remove_user_key()
end

解决方案

I will suggest you to use access_by_lua
in nginx.conf

location / {
                #host and port to fastcgi server
                default_type text/html;
                set $URL "http://$http_host$request_uri";
                access_by_lua_file /home/lua/cache.lua;
                proxy_pass http://$target;
                -------
                ---------

in cache.lua file you can do something like :

if ngx.req.get_method() == "POST" then
    -- check if request method is POST 
    -- implement your logic 
    return
end

这篇关于如何使用 Nginx 和 Lua 操作 POST 请求的 JSON 正文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆