如何使用Nginx和Lua操作POST请求的JSON主体?

时间:2014-04-01 14:01:59

标签: nginx lua 3scale

我正在进行概念验证,以演示如何在堆栈中实现3scale。在一个示例中,我想要执行一些POST 请求正文操作来创建API外观,该外观将可能是旧API格式的内容映射到新的内部API格式。例如。改变像

这样的东西
{ "foo" : "bar" , "deprecated" : true }

{ "FOO" : "bar" }

Lua module docs for content_by_lua,这似乎是合适的方法

  

请勿在同一位置使用此指令和其他内容处理程序指令。例如,该指令和proxy_pass指令不应在同一位置使用。

我的理解是content_by_lua是一个像proxy_pass这样的内容处理程序,每个位置只能使用其中一个。

我认为没有办法删除 proxy_pass ,因为这是代理工作方式的基础,因此可以在单独的位置捕获请求,使用 content_by_lua ,然后转到实施 proxy_pass 的位置,或者是否有更合适的rewrite_by_lua方法?


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

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

3 个答案:

答案 0 :(得分:6)

我建议你使用access_by_lua
在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;
                -------
                ---------
在cache.lua文件中

可以执行以下操作:

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

答案 1 :(得分:4)

添加Prashant已经提到的内容:当您从3scale下载Nginx配置文件时,您会注意到包含一个Lua文件。此文件已从access_by_lua_file调用。

在我看来,该文件是添加您的身体操控代码的最佳位置。在发送proxy_pass到您的API服务器之前,它将针对每个请求执行。

此外,this是一篇非常好的深入博客文章,介绍如何使用Nginx中的Lua完成对请求的不同转换:

答案 2 :(得分:1)

最近我不得不在post请求中根据JSON值操作上游,我觉得这很有用:NGINX LUA and JSON

这是基本配置,但提供了如何操作的想法。