Common nginx + Lua Configuration Techniques
- Routing Requests to a Specific URL The following configuration forwards incoming requests to a backend service running on a different host and port:
location /api/auth/login {
proxy_pass http://backend-server:30900/api/auth/login;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
- Forwarding Cookies and Rewriting Cookie Path When a backend service returns a Cookie with a subdirectory path (e.g., /usermanager), the frontend application cannot read it. This example rewrites the cookie path to the root directory:
location /userportal/login {
proxy_pass http://user-service:7200/userportal/login;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
header_filter_by_lua_block {
local response_cookies = ngx.resp.get_headers()["Set-Cookie"]
if response_cookies then
if type(response_cookies) == "string" then
local rewritten = string.gsub(response_cookies, "Path=/userportal", "Path=/")
ngx.header["Set-Cookie"] = rewritten
return
end
for index, cookie_value in ipairs(response_cookies) do
response_cookies[index] = string.gsub(cookie_value, "Path=/userportal", "Path=/")
end
ngx.header["Set-Cookie"] = response_cookies
end
}
}
- Modifying Response Body to Replace Internal URLs Some backend endpoints (such as OAuth redirect callbacks) return internal URLs that are not accessible from outside the network. This configuration intercepts the response and replaces internal hostnames with public-facing addresses:
location /api/oauth/token {
proxy_pass http://auth-service:30900/api/oauth/token;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 360;
proxy_buffering off;
body_filter_by_lua_block {
local chunk_data, end_of_file = ngx.arg[1], ngx.arg[2]
local context = ngx.ctx
if not context.payload then
context.payload = ""
end
context.payload = context.payload .. chunk_data
ngx.arg[1] = nil
if end_of_file then
local json_parser = require "cjson"
local parse_success, json_data = pcall(json_parser.decode, context.payload)
if not parse_success then
return
end
if json_data.status == "302" and type(json_data.message) == "string" then
ngx.log(ngx.ERR, "Original URL: ", json_data.message)
local external_url = string.gsub(json_data.message, "http://[^/]+", "http://public-host:28080")
json_data.message = external_url
ngx.log(ngx.ERR, "Transformed URL: ", json_data.message)
local modified_response = json_parser.encode(json_data)
ngx.arg[1] = modified_response
else
ngx.arg[1] = context.payload
end
end
}
}
- Selectiev URL Redirection This configuration redirects specific frontend resource requests to a unified prefix path, ensuring compatibility between internal and external access patterns:
location / {
rewrite_by_lua_block {
local request_path = ngx.var.uri
if request_path:match("^/asr/bundle.js") or request_path:match("^/favicon.ico") then
ngx.req.set_uri("/gateway" .. request_path)
end
}
proxy_pass http://backend-server:30900/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 360;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
These techniques leverage nginx's integration with Lua to perform dynamic request and response modifications without requiring changes to the backend application code.