在 nginx 中,我想根据访问和代理标头重定向用户。当我将其放入响应标头时,它们会在浏览器中正确显示。但是当在 lua 中使用
if
进行重定向时,它不会。
对于具有访问权限的用户,应用程序创建字符串
isprotectedfalse
,对于客人,我得到 isprotected
add_header X-User-Access-Flag $userinfo$arg_limit$upstream_http_x_doc_protection; #this works
if ($http_x_user_access_flag = "isprotected") { #this doesnt
return 302 $scheme://$http_host$uri?limit=true;
}
和类似的代码,但在 lua 中:
rewrite_by_lua_block {
local params = ngx.req.get_uri_args()
local limit = params["limit"]
local headers = ngx.resp.get_headers()
local useraccesss = headers["X-User-Access-Flag"]
if useraccesss == "isprotected" and limit == nil then
local delimiter = (ngx.var.is_args == "" or ngx.var.is_args == nil) and "?" or "&"
local new_url = ngx.var.request_uri .. delimiter .. "limit=true"
return ngx.redirect(new_url)
end
}
为什么它没有按预期重定向?
编辑: 来自使用
header_filter_by_lua_block
我已经设法从
ngx.var['upstream_http_x_user_access_flag']
访问它们,它在lua块之前使用来设置X-User-Access-Flag(来自proxy_pass)。但遗憾的是,重定向尝试时服务器出现错误(已发送标头)。似乎此时标头已经发送(但我仍然可以在那里设置一个有效的自定义标头?!所以这很令人困惑......)
我无法从
ngx.var
访问这样的rewrite_by_lua_block
,因为这还没有执行proxy_pass
。我如何访问此变量 after
auth
+ proxy_pass
并根据获取的标头进行重定向?
为了扩展mandy8055的评论,当您考虑Nginx HTTP阶段时,您确实会看到一个请求会经历几个阶段或“阶段”,每个阶段都是为特定任务而设计的。
rewrite_by_lua_block
。这就是 URL 修改发生的地方。proxy_pass
指令在此阶段起作用,从上游服务器获取内容。header_filter_by_lua_block
。这是可以操纵来自上游服务器的响应标头的地方。在您的情况下,
rewrite_by_lua_block
在Rewrite
阶段执行,该阶段发生在Content
阶段之前,其中proxy_pass
设置上游标头。rewrite_by_lua_block
中的 Lua 脚本尝试访问 proxy_pass
设置的标头时,它们尚不可用,因为 proxy_pass
尚未执行。
access_by_lua_block
:它在proxy_pass
阶段之后执行,这应该允许您访问上游服务器设置的标头。
access_by_lua_block {
local headers = ngx.req.get_headers()
local useraccess = headers["X-User-Access-Flag"]
local limit = ngx.var.arg_limit
if useraccess == "isprotected" and not limit then
return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.request_uri .. "?limit=true")
end
}
确保
X-User-Access-Flag
标头已正确设置并从上游服务器传递到 Nginx。access_by_lua_block
应放置在服务器块中 proxy_pass
指令之后。