Return after ngx.redirect

Hello fellows, another question;

My plugin is retrieving a JWT in header and passing it to another service. My question is, how to handle the responses? Till now I read here:

https://openresty-reference.readthedocs.io/en/latest/Lua_Nginx_API/?q=rewrite&check_keywords=yes&area=default#ngxredirect

That redirects are the end of the call, but none of the other methods helped me. I tried ngx.req.set_uri(uri, jump?) and ngx.req.set_uri_args(args).

The sample code I’m using:

local singletons = require "kong.singletons"

local BasePlugin = require “kong.plugins.base_plugin”
local responses = require “kong.tools.responses”
local constants = require “kong.constants”
local utils = require “kong.tools.utils”
local multipart = require “multipart”
local cjson = require “cjson”
local url = require “socket.url”
local basic_serializer = require “kong.plugins.log-serializers.basic”
local Router = require “kong.core.router”
local reports = require “kong.core.reports”
local balancer = require “kong.core.balancer”
local certificate = require “kong.core.certificate”
local string_format = string.format
local ngx_set_header = ngx.req.set_header
local get_method = ngx.req.get_method
local req_set_uri_args = ngx.req.set_uri_args
local req_get_uri_args = ngx.req.get_uri_args
local req_set_header = ngx.req.set_header
local req_get_headers = ngx.req.get_headers
local req_clear_header = ngx.req.clear_header
local req_set_method = ngx.req.set_method
local ngx_decode_args = ngx.decode_args
local ngx_re_gmatch = ngx.re.gmatch
local cjson_encode = cjson.encode
local ipairs = ipairs
local request = ngx.request

local CtkHandler = BasePlugin:extend()
CtkHandler.PRIORITY = 3505
CtkHandler.VERSION = “0.1.0”
ngx.log(ngx.WARN, “— ctk — JUST EXTENDED THE BASE PLUGIN”)

function CtkHandler:new()
CtkHandler.super.new(self, “ctk”)
ngx.log(ngx.WARN, “— ctk — INSTACIATED ITSELF”)
end

function CtkHandler:access(conf)
function CtkHandler:access(conf)
CtkHandler.super.access(self)
ngx.log(ngx.WARN, “### ctk — STARTED THE ACCESS PROCESS”)

token = tostring(ngx.req.get_headers()["Authorization"])
ngx.log(ngx.WARN, token)

--ngx.req.set_header("Content-Type", "application/json")
--ngx.req.set_uri("/")
url = "http://XXX.XXX.XXX.XXX:3315/v1/usr/access/" .. token
--ngx.escape_uri(token)
redirect = ngx.redirect(url, ngx.HTTP_TEMPORARY_REDIRECT)
get = ngx.HTTP_GET
ngx.log(ngx.WARN, get)

if ngx.HTTP_GET == ngx.HTTP_OK then
        ngx.log(ngx.WARN, "### 200 ###")
        return
else
        ngx.redirect("/authenticate", ngx.HTTP_UNAUTHORIZED)
        ngx.log(ngx.WARN, "### 401 ###")
end
if redirect == ngx.HTTP_OK then
        return
        ngx.log(ngx.WARN, "### STATUS 200 OK ###")
else
        ngx.redirect("/authenticate", ngx.HTTP_UNAUTHORIZED)
        ngx.log(ngx.WARN, "### STATUS 401 UNAUTHORIZED ###")
end
--ngx.req.set_uri_args("/" .. token)
--ngx.log(ngx.WARN, url)

end
end

return CtkHandler

And here are the services and routes created, I installed the plugin above on top of the service below.

curl -i -X POST http://localhost:8001/services/
-d ‘name=access’
-d ‘url=http://XXX.XXX.XXX.XXX:3315/v1/usr/access/’

curl -i -X POST http://localhost:8001/routes/
-d ‘hosts[]=localhost’
-d ‘paths[]=/access’
-d ‘service.id=4deb0aff-63a7-4af3-a2e6-7b9e9b8800bc’

Slightly confused on your question here. Can you be precise as to what you are using the JWT header for? If you are just asking how to do a proper nginx redirect in a plugin its like this:

return ngx.redirect(endpoint)

Doing this will redirect a proxy transaction to whatever endpoint you desire during a tx and to me looks like you are using it correctly. Can you explain Client -> Backend Flow and how this plugin you are building is supposed to help you?

Is it that you intend one Kong service to be able to call an entirely different Kong service(via redirect) based on a JWT value?

Hi Jeremy,

  1. I have a service that generates JWT’s for users.
  2. The client that has the JWT will consume more services, so I’m using Kong to validate this Jwt against the service that generated it.
  3. My plugin will receive the JWT in the client’s header, and it will have to send to the service that generated it to see if the JWT is valid or not.
  4. The service does validate the JWT when you pass it as part of the URI to: service/access/{JWT}
  5. The service doesn’t validade the JWT if I send it in the header.

Till now my plugin retrieves the JWT in header and send it to the service. The service answer 200 (if JWT ok) and 500 (if not). From here I Would like to continue writing a few more dozen lines of code to actually do other things with the client JWT, e.g.

  1. If the status was OK, the plugin will see what the client was looking for in the first place, then redirect accordingly.
  2. If the status wasn’t OK, the plugin will just send a 401 (not the original message from my service, which was 500).

Using the methods to transform the URI didn’t helped me, but then again, I do not know if all of them are available in Kong 0.13

EDIT:

Using the ngx.var.upstream_uri I get:

2018/05/24 10:32:52 [error] 3147#0: *10 invalid port in upstream

Here the code excerpt:

uri = "http://192.168.50.172:3315/v1/usr/access/" .. token
ngx.var.upstream_uri = uri

Solved my problem sending a http request. Thanks for your time.

            ura = conf.url .. token
            local data = ""
            local function collect(chunk)
                    if chunk ~= nil then
                    data = data .. chunk
                    end
            return true
            end
            local ok, statusCode, headers, statusText = http.request {
                    method = "POST",
                    url = ura,
                    sink = collect
            }
1 Like