语法: access_by_lua <lua-script-str>
环境: http, server, location, location if
阶段: access tail
扮演 access 阶段处理,对每次请求执行在<lua-script-str>
中指名的 Lua 代码。
这些 Lua 代码可以调用全部 API,并作为一个新的协程,在一个独立的全局环境中执行(就像一个沙盒)。
注意:本指令的处理总是在标准ngx_http_access_module的后面。所以下面的示例可以按照预期工作:
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
access_by_lua '
local res = ngx.location.capture("/mysql", { ... })
...
';
# proxy_pass/fastcgi_pass/...
}
换句话说,如果一个客户端 IP 地址在黑名单中,它将在 access_by_lua中的 Mysql 复杂认证请求之前被拒绝。
注意,ngx_auth_request模块可以近似的被access_by_lua实现:
location / {
auth_request /auth;
# proxy_pass/fastcgi_pass/postgres_pass/...
}
使用 ngx_lua 是这样:
location / {
access_by_lua '
local res = ngx.location.capture("/auth")
if res.status == ngx.HTTP_OK then
return
end
if res.status == ngx.HTTP_FORBIDDEN then
ngx.exit(res.status)
end
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
';
# proxy_pass/fastcgi_pass/postgres_pass/...
}
和其他access阶段处理实现,access_by_lua将不能运行在子请求中。
注意,在access_by_lua处理内部,当调用ngx.exit(ngx.OK)
时,nginx请求将继续下一阶段的内容处理。要在access_by_lua处理中终结当前请求,调用ngx.exit,成功的请求设定 status >= 200 (ngx.HTTP_OK
) 并 status < 300 (ngx.HTTP_SPECIAL_RESPONSE
),失败的请求设定ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
(或其他相关的)。
English source:
syntax: access_by_lua <lua-script-str>
context: http, server, location, location if
phase: access tail
Acts as an access phase handler and executes Lua code string specified in <lua-script-str>
for every request.
The Lua code may make API calls and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).
Note that this handler always runs after the standard ngx_http_access_module. So the following will work as expected:
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
access_by_lua '
local res = ngx.location.capture("/mysql", { ... })
...
';
# proxy_pass/fastcgi_pass/...
}
That is, if a client IP address is in the blacklist, it will be denied before the MySQL query for more complex authentication is executed by access_by_lua.
Note that the ngx_auth_request module can be approximated by using access_by_lua:
location / {
auth_request /auth;
# proxy_pass/fastcgi_pass/postgres_pass/...
}
can be implemented in ngx_lua as:
location / {
access_by_lua '
local res = ngx.location.capture("/auth")
if res.status == ngx.HTTP_OK then
return
end
if res.status == ngx.HTTP_FORBIDDEN then
ngx.exit(res.status)
end
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
';
# proxy_pass/fastcgi_pass/postgres_pass/...
}
As with other access phase handlers, access_by_lua will not run in subrequests.
Note that when calling ngx.exit(ngx.OK)
within a access_by_lua handler, the nginx request processing control flow will still continue to the content handler. To terminate the current request from within a access_by_lua handler, calling ngx.exit with status >= 200 (ngx.HTTP_OK
) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE
) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
(or its friends) for failures.