共计 1954 个字符,预计需要花费 5 分钟才能阅读完成。
最近想整一个服务,想用来获取用户的的请求IP,之前项目中对一些接口存在一些黑白名单限制,都是在后端中做处理,调用方经常会找博主调试,遂想直接在openresty中提供个接口用来响应客户端请求地址给调用方,省得一直找我查日志。。。
1.响应json数据
在nginx中如果要响应json数据,可以使用如下方式:
location /nginx/json/ {
add_header Content-Type 'application/json; charset=utf-8';
return 200 '{"site":"xadocker.cn","author":"xadocker"}';
}
而在openresty中,需要引入cjson模块解析
json = require "cjson"
obj = {a=1,b=2,c=3}
res_json = json.encode(obj)
2.获取用户得请求ip
默认情况下,nginx中得$remote_addr就是客户端请求ip,但是如果前面有反向代理,就会获取到错误的地址。按照一般业内规范,存在代理时都会将真正的客户端ip转存在在header中,一般可能有以下两个header参数:
- X-REAL-IP
- X_FORWARDED_FOR
所以最终我们只需要从上面两个参数和$remote_addr共三个参数中取得最终值:
- 如果header中存在任意一个,则为客户端ip
- 如果header那两个参数不存在则使用$remote_addr为客户端地址
所以我们的lua逻辑如下
CLIENT_IP = ngx.req.get_headers()["X_real_ip"]
if CLIENT_IP == nil then
CLIENT_IP = ngx.req.get_headers()["X_Forwarded_For"]
end
if CLIENT_IP == nil then
CLIENT_IP = ngx.var.remote_addr
end
if CLIENT_IP == nil then
CLIENT_IP = "unknown"
end
最终我们location块如下
location /lua/getRequestMeta/ {
content_by_lua_block{
ngx.header['Content-Type'] = 'application/json; charset=utf-8'
local headers=ngx.req.get_headers()
local ip=headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr
json = require "cjson"
local obj = {
request_time = ngx.var.request_time,
host = ngx.var.host,
scheme = ngx.var.scheme,
referer = ngx.var.http_referer,
content_type = ngx.var.content_type,
http_cookie = ngx.var.http_cookie,
user_agent = ngx.var.http_user_agent,
request_method = ngx.var.request_method,
server_protocol = ngx.var.server_protocol,
request_uri = ngx.var.request_uri,
time = ngx.var.time_iso8601,
status = ngx.var.status,
client = {
client_ip = ip,
client_port = ngx.var.remote_port,
client_user = ngx.var.remote_user,
}
}
res_json_data = json.encode(obj)
ngx.say(res_json_data)
}
}
最后获取到的响应如下
{
"host": "openresty.xadocker.cn",
"request_time": "0.000",
"request_uri": "/lua/getRequestMeta/",
"status": "000",
"time": "2021-04-03T23:41:21+08:00",
"user_agent": "PostmanRuntime/7.29.0",
"client": {
"client_ip": "119.130.128.177",
"client_port": "52578",
"client_user": "xadocker"
},
"scheme": "http",
"request_method": "GET",
"server_protocol": "HTTP/1.1"
}
正文完